Dateilisten mittels find und xargs?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
sonya
Beiträge: 84
Registriert: 28.07.2007 07:55:33

Dateilisten mittels find und xargs?

Beitrag von sonya » 26.11.2009 17:58:59

Hallo,

ich habe ein Problem mit der Erstellung von Dateilisten.
ein:
cd /home/sonya/test/dateiliste
dort:
find . -name "*.tiff" -print0 | xargs -0 ls >liste.txt
erstellt im Ordner
cd /home/sonya/test/dateiliste
eine "liste.txt" mit dem Inhalt der Verzeichnisstruktur und den jeweils darin befindlichen tiff Dateien.
Die "liste.txt" soll jedoch in den jeweiligen Sub- und Subsubverzeichnissen mit den jeweiligen darin befindlichen Dateien hineingeschrieben werden.
Also nicht eineDatei "liste.txt" in Hauptverzeichnis sondern in jeden einzelnen Subvereichnis innerhalb der gesamten Verzeichnistiefe eine "liste.txt" mit einer Liste der jeweiligen Dateien die im jeweiligen Subverzeichnis liegen.

Das heist ja, xarg müsste die Verzeichnisstruktur übergeben bekommen und dann in jedes Subverzeichnis hinein kriechen und dort das jeweilige "ls >liste.txt" ausführen.
Nur wie kann das gelöst werden? Kann das Problem überhaupt mittels xargs gelöst werden oder muss da schwere Perlprogrammierung aufgefahren werden?

LG
Sonya

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Dateilisten mittels find und xargs?

Beitrag von Meillo » 26.11.2009 18:28:57

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | awk '{ system("basename "$1" >> `dirname "$1"`/liste.txt") }'
Use ed once in a while!

sonya
Beiträge: 84
Registriert: 28.07.2007 07:55:33

Re: Dateilisten mittels find und xargs?

Beitrag von sonya » 26.11.2009 20:26:45

Meillo hat geschrieben:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | awk '{ system("basename "$1" >> `dirname "$1"`/liste.txt") }'
Hallo Meillo,

das ist ja erstaunlich! Ein Einzeiler kann so etwas 8O
AWK ist ja auch sehr mächtig. Habe mich damit überhaupt noch nicht auseinander gesetzt :oops:
Nur wie bekomme ich die Zeilen (Dateinamen) in "liste.txt" alphabetisch sortiert? Viele Dateien haben Namen der Art 01-xyz.tiff bis 09-xyz.tiff und weiter mit 10..., 11... Dachte das funktioniert automatisch nach Dateinamen.
Muss ich da zum Sortieren noch einmal sed bei allen "liste.txt" durchlaufen lassen.

In der Tiefe der Verzeichnisse gibt es Dateien und Verzeichnisse mit Leerzeichen und Zeichen die nicht A-z, a-z und 0-9. Mit denen funktioniert Dein Beispiel nicht. Wird im Ablauf des Skripts solch ein Verzeichnis gefunden, wird eine Fehlermeldung ausgegeben. Ebenso bei entsprechenden Dateien.
Das ist jedoch nicht tragisch. Aus den Verzeichnissen und Dateien müssen alle Zeichen zu entfernt bzw. umbenannt werden, die nicht A-z, a-z und 0-9 entsprechen und Leerzeichen werden durch "_" ersetzt. Da bin ich gerade dabei. pyrename bzw. krename sind da eine gute Hilfe.

LG
Sonya

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Dateilisten mittels find und xargs?

Beitrag von rendegast » 26.11.2009 20:36:01

Noch ein sort zwischen find und awk:

Code: Alles auswählen

... | sort -n | ...[/b]
Die Sortierung kannst Du bezüglich Leer- und Sonderzeichen beeinflussen, ich verwende

Code: Alles auswählen

export LC_COLLATE=POSIX
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Dateilisten mittels find und xargs?

Beitrag von chrisbra » 26.11.2009 20:45:27

find . -type d -execdir sh -c 'find $1 -mindepth 1 -maxdepth 1 >$1/liste' find-sh '{}' \;

Grüße,
Christian
Meine Whishlist
:wq!

sonya
Beiträge: 84
Registriert: 28.07.2007 07:55:33

Re: Dateilisten mittels find und xargs?

Beitrag von sonya » 01.12.2009 08:53:18

Hallo Meillo, rendegast und Christian,

vielen Dank für Eure Hife. Die Sache funktioniert jetzt.
Meillo hat geschrieben:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | awk '{ system("basename "$1" >> `dirname "$1"`/liste.txt") }'
Was ich nicht "ganz" verstehe ist, ja fast alles hinter awk :oops:
Ich schaffe es einfach nicht, ganz hinten den Verzeichnisnahmen in denen sich die Dateien befinden also verzeichnis.txt" anstelle "liste.txt" einzusetzen.

Code: Alles auswählen

... ...`dirname "$1"`/"$1"-liste.txt") }' 
bringt erwartungsgemäß einen Fehler.

Code: Alles auswählen

... ...`dirname "$1"`/`dirname "$1"`-liste.txt") }' 
bringt einen Fehler, ebenso wie:

Code: Alles auswählen

... ...`dirname "$1"`/'$1'-liste.txt") }' 
Es kann doch nicht soo schwer sein, nicht "liste.txt" sondern den "jeweiligerVerzeichnisnahme-liste.txt" auszugeben :oops:

LG
Sonya

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Dateilisten mittels find und xargs?

Beitrag von Meillo » 01.12.2009 09:37:23

sonya hat geschrieben:
Meillo hat geschrieben:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | awk '{ system("basename "$1" >> `dirname "$1"`/liste.txt") }'
Ich schaffe es einfach nicht, ganz hinten den Verzeichnisnahmen in denen sich die Dateien befinden also verzeichnis.txt" anstelle "liste.txt" einzusetzen.
Du meinst vermutlich bei ``foo/bar/baz/a.tiff'' soll es ``baz.txt'' sein.

Code: Alles auswählen

... ...`dirname "$1"`/"$1"-liste.txt") }' 
bringt erwartungsgemäß einen Fehler.
In $1 wird oft ein Slash enthalten sein. Der darf in Dateinamen aber nicht vorkommen. Nicht-existente Unterverzeichnisse werden aber nicht angelegt.

Du wirst `basename \`dirname $1\` ` verwenden müssen.

Code: Alles auswählen

... ...`dirname "$1"`/`basename \`dirname "$1"\` `-liste.txt") }' 
Heute Nachmittag werde ich vermutlich wieder mehr Zeit haben. Dann kann ich's dir nochmal schön in awk machen, ohne soviele Shellbefehle und Verschachtungen.
Use ed once in a while!

sonya
Beiträge: 84
Registriert: 28.07.2007 07:55:33

Re: Dateilisten mittels find und xargs?

Beitrag von sonya » 01.12.2009 15:14:40

Hallo Meillo,
vielen Dank für deine Bemühungen
Meillo hat geschrieben:
sonya hat geschrieben:
Meillo hat geschrieben:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | awk '{ system("basename "$1" >> `dirname "$1"`/liste.txt") }'
Ich schaffe es einfach nicht, ganz hinten den Verzeichnisnahmen in denen sich die Dateien befinden also verzeichnis.txt" anstelle "liste.txt" einzusetzen.
Du meinst vermutlich bei ``foo/bar/baz/a.tiff'' soll es ``baz.txt'' sein.
Ja, genau so.

Meillo hat geschrieben:
sonya hat geschrieben:

Code: Alles auswählen

... ...`dirname "$1"`/"$1"-liste.txt") }' 
bringt erwartungsgemäß einen Fehler.
In $1 wird oft ein Slash enthalten sein. Der darf in Dateinamen aber nicht vorkommen. Nicht-existente Unterverzeichnisse werden aber nicht angelegt.


Du wirst `basename \`dirname $1\` ` verwenden müssen.

Code: Alles auswählen

... ...`dirname "$1"`/`basename \`dirname "$1"\` `-liste.txt") }' 
Das mit dem Slash habe ich nicht gewusst
Doch egal wie ich Deinen Vorschlag anwende, Diese Zeichen " ` " durch " ' " getauscht, auch den Slash per Backslash "auskommentiert", Deine Variante mag noch nicht richtig funktionieren?

LG Sonya

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Dateilisten mittels find und xargs?

Beitrag von Meillo » 01.12.2009 16:14:50

Meillo hat geschrieben:Heute Nachmittag werde ich vermutlich wieder mehr Zeit haben. Dann kann ich's dir nochmal schön in awk machen, ohne soviele Shellbefehle und Verschachtungen.
Hier nun die schöne Version:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | sort | awk -F/ '{
  OFS=FS;
  f=$NF; NF--;
  list=$0"/"$NF"-liste.txt";
  print f >>list;
  close(list);  # because number of open file descriptors is limited
}'
Erklärung des Codes:
Fieldseparator und Output Fieldseparator werden auf `/' gesetzt. Das letzte Feld ist somit der Basename. Die Anzahl der Felder wird reduziert, damit fällt bleibt nur noch der Dirname übrig.

list beinhaltet den Namen der Datei in die die Liste gespeichert werden soll. $0 ist der Dirname. $NF ist das letzte Glied in $0.

Dann wird der Eintrag geschrieben und danach die Datei geschlossen (um nicht an's File-Deskriptor-Limit zu stoßen).
Use ed once in a while!

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Dateilisten mittels find und xargs?

Beitrag von chrisbra » 01.12.2009 16:25:49

sonya hat geschrieben: Es kann doch nicht soo schwer sein, nicht "liste.txt" sondern den "jeweiligerVerzeichnisnahme-liste.txt" auszugeben :oops:
Ich werf nochmal meine Lösung ein:
find . -type d -execdir sh -c 'find "$1" -mindepth 1 -maxdepth 1 >"$1"/"${1##*/}"-liste' find-sh '{}' \;
Meine Whishlist
:wq!

sonya
Beiträge: 84
Registriert: 28.07.2007 07:55:33

Re: Dateilisten mittels find und xargs?

Beitrag von sonya » 01.12.2009 16:30:19

Hallo Meillo,

perfekt! Das ist ja genial! DANKE!
Und auch noch mit der Erklärung. Ehrlich, ohne Erklärung wäre es schwer zu durchschauen.
Heute Abend ein Glas Rotwein auf Dein Wohl.

Vielen Dank für die Hilfe
Sonya

Meillo hat geschrieben:
Meillo hat geschrieben:Heute Nachmittag werde ich vermutlich wieder mehr Zeit haben. Dann kann ich's dir nochmal schön in awk machen, ohne soviele Shellbefehle und Verschachtungen.
Hier nun die schöne Version:

Code: Alles auswählen

find /home/sonya/test/dateiliste -name "*.tiff" | sort | awk -F/ '{
  OFS=FS;
  f=$NF; NF--;
  list=$0"/"$NF"-liste.txt";
  print f >>list;
  close(list);  # because number of open file descriptors is limited
}'
Erklärung des Codes:
Fieldseparator und Output Fieldseparator werden auf `/' gesetzt. Das letzte Feld ist somit der Basename. Die Anzahl der Felder wird reduziert, damit fällt bleibt nur noch der Dirname übrig.

list beinhaltet den Namen der Datei in die die Liste gespeichert werden soll. $0 ist der Dirname. $NF ist das letzte Glied in $0.

Dann wird der Eintrag geschrieben und danach die Datei geschlossen (um nicht an's File-Deskriptor-Limit zu stoßen).

Antworten