Schreiben von Dateien in einem Unterverzeichnis in eine CSV-Datei und Speichern im übergeordneten Verzeichnis in der Linux-Befehlszeile

Schreiben von Dateien in einem Unterverzeichnis in eine CSV-Datei und Speichern im übergeordneten Verzeichnis in der Linux-Befehlszeile

Ich habe ein Verzeichnis namens „dir“ und darin ein Unterverzeichnis namens „subdir“. Das Unterverzeichnis enthält viele Dateien. Ich möchte eine Liste dieser Dateien in eine CSV-Datei schreiben und sie mit einer Befehlszeile unter Linux im Verzeichnis „dir“ speichern. Mein Code erstellt die CSV-Datei, speichert sie aber im Unterverzeichnis, aber nicht im Verzeichnis. Was mache ich falsch? Ich bin im Verzeichnis „dir“;

dir$ ls subdir >names.csv

Antwort1

Als einfachere Alternative können Sie in das Unterverzeichnis cdn wechseln und verwenden

printf "%s\n" * >../list.csv

Dadurch erhalten Sie eine durch Zeilenumbrüche getrennte und durch Zeilenumbrüche abgeschlossene Liste ohne Kommas. Sie können sie als degradierte CSV-Datei mit nur einer Spalte sehen.

Wenn Sie versteckte Dateien (Dateien, deren Namen mit einem Punkt beginnen) einschließen möchten, können Sie * .*anstelle der einzigen verwenden *. Wenn Sie die Verzeichnisnamen . und .. ausschließen möchten, verwenden Sie * .[^.]* ..?*stattdessen. Insgesamt:

printf "%s\n" *             >../list.csv   # For non-hidden files.
printf "%s\n" * .*          >../list.csv   # For all files.
printf "%s\n" * .[^.]* ..?* >../list.csv   # For all files but `.` and `..`.

Bedenken Sie jedoch, dass Dateinamen in Linux selbst Zeilenumbrüche enthalten können. Tatsächlich ist das einzige eindeutige Einzelbyte-Trennzeichen für Dateinamen das Null-Byte.


Update aufgrunddieser Kommentar:

Nehmen wir an, Sie haben eine beliebige Anzahl von Unterverzeichnissen, deren nicht versteckten Inhalt Sie in separaten Dateien im gemeinsamen übergeordneten Verzeichnis katalogisieren möchten. (Das Sammeln aller Namen in einer Datei ist viel kürzer, siehediese elegante Lösung. Und, um die Wahrheit zu sagen, ich habe Ihren Kommentar nicht sorgfältig genug gelesen.) Dies kann in diesem übergeordneten Verzeichnis (in Ihrem Fall dir) erreicht werden durch

find . -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd {}; printf "%s\n" * >../$(basename {}).csv' \;

Hierzu sind die Programme find, bash, und erforderlich basename.

Bei der Verwendung sollten Sie besonders darauf achten, dass das Verzeichnis keine Dateien enthält, deren Namen mit den automatisch generierten CSV-Listen in Konflikt stehen.

Und so funktioniert es: findbetrachtet jede Datei, die genau eine Verzeichnisebene unter dem aktuellen Verzeichnis liegt ( .) – das ist, was -mindepth 1 -maxdepth 1tut –: Wenn es ein Verzeichnis ist ( -type d), führt es ( -exec) den Befehl zwischen -execund dem abschließenden aus \;, nachdem die leeren Klammern ( {}) durch den Namen dieses Verzeichnisses ersetzt wurden. Wenn wir diesen Namen mit bezeichnen <SUBDIR>, ergibt dies

bash -c 'cd <SUBDIR>; printf "%s\n" * >../$(basename <SUBDIR>).csv'

Dies startet bashin einem Unterprozess und führt das Argument der -cOption als Shell-Skript aus, und zwar

cd <SUBDIR>;
printf "%s\n" * >../$(basename <SUBDIR>).csv

was so ziemlich dasselbe ist wie oben. Hier der Ausdruck

$(basename <SUBDIR>)

wird zum Basisnamen von erweitert <SUBDIR>. Dies ist notwendig, da <SUBDIR>in Ihrem Fall durch ./subdir1, ./subdir2 usw. iteriert wird. Die entsprechenden Basisnamen sind subdir1, subdir2 usw.

Antwort2

Dies erreichen Sie mit demfürSchleife.

Wenn ich das richtig verstehe, möchten Sie eine Liste der Dateien im Unterverzeichnis erhalten. Gehen Sie also so vor:

$ cd dir
$ for files in subdir/*;do echo $files|cut -d '/' -f 2 >>filelist.csv;done

Jetzt können Sie sehen, dass in Ihrem Verzeichnis „Dir“ eine Datei mit dem Namen „filelist.csv“ erstellt wurde.

verwandte Informationen