it-swarm.com.de

Wie verwende ich eine For-Each-Schleife, um Dateipfade in Bash zu durchlaufen?

Der folgende Befehl versucht, alle *.txt Dateien im aktuellen Verzeichnis und verarbeiten Sie diese nacheinander:

for line in "find . -iname '*.txt'"; do 
     echo $line
     ls -l $line; 
done

Warum erhalte ich folgenden Fehler:

ls: invalid option -- 'e'
Try `ls --help' for more information.
49
0x90

Hier ist eine bessere Möglichkeit, eine Schleife über Dateien durchzuführen, da Leerzeichen und Zeilenumbrüche in Dateinamen behandelt werden:

find . -type f -iname "*.txt" -print0 | while IFS= read -r -d $'\0' line; do
    echo "$line"
    ls -l "$line"    
done
118
dogbane

Die for- Schleife durchläuft jeden (durch Leerzeichen getrennten) Eintrag in der angegebenen Zeichenfolge.

Sie führen den Befehl find nicht aus, sondern geben ihn als Zeichenfolge an (die von der for-Schleife durchlaufen wird). Verwenden Sie anstelle der doppelten Anführungszeichen entweder Backticks oder $():

for line in $(find . -iname '*.txt'); do 
     echo "$line"
     ls -l "$line"
done

Wenn Ihre Dateipfade/-namen Leerzeichen enthalten, schlägt diese Methode fehl (da die for- Schleife durch durch Leerzeichen getrennte Einträge iteriert). Stattdessen ist es besser, die in dogbanes answer beschriebene Methode zu verwenden.


So klären Sie Ihren Fehler:

Wie gesagt, for line in "find . -iname '*.txt'"; durchläuft alle durch Leerzeichen getrennten Einträge.

  • finden
  • .
  • -iname
  • '* .txt' (glaube ich ...)

Die ersten beiden führen (neben dem unerwünschten Verhalten) nicht zu einem Fehler, aber der dritte ist problematisch, wenn er ausgeführt wird:

ls -l -iname

Viele (Bash) -Befehle können Optionen für einzelne Zeichen kombinieren, also -iname ist das gleiche wie -i -n -a -m -e. Und voila: dein invalid option -- 'e' Error!

19
Veger

Kompaktere Version, die mit Leerzeichen und Zeilenumbrüchen im Dateinamen arbeitet:

find . -iname '*.txt' -exec sh -c 'echo "{}" ; ls -l "{}"' \;
18
jserras

Verwenden Sie Befehlssubstitution anstelle von Anführungszeichen, um find auszuführen, anstatt den Befehl als Zeichenfolge zu übergeben:

for line in $(find . -iname '*.txt'); do 
     echo $line
     ls -l $line; 
done
3
Jens Erat