
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: find
betrachtet jede Datei, die genau eine Verzeichnisebene unter dem aktuellen Verzeichnis liegt ( .
) – das ist, was -mindepth 1 -maxdepth 1
tut –: Wenn es ein Verzeichnis ist ( -type d
), führt es ( -exec
) den Befehl zwischen -exec
und 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 bash
in einem Unterprozess und führt das Argument der -c
Option 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.