TL; DR: Wenn Sie nur hier sind, um die richtigste Antwort zu erhalten, möchten Sie wahrscheinlich meine persönliche Präferenz find . -name '*.txt' -exec process {} \;
(siehe unten in diesem Beitrag). Wenn Sie Zeit haben, lesen Sie den Rest durch, um verschiedene Möglichkeiten und die Probleme mit den meisten von ihnen zu sehen.
Die vollständige Antwort:
Der beste Weg hängt davon ab, was Sie tun möchten, aber hier sind einige Optionen. Solange keine Datei oder kein Ordner im Teilbaum Leerzeichen enthält, können Sie die Dateien einfach durchlaufen:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
Etwas besser, schneiden Sie die temporäre Variable aus x
:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
Es ist viel besser zu globieren, wenn du kannst. White-Space-Safe für Dateien im aktuellen Verzeichnis:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
Durch Aktivieren der globstar
Option können Sie alle übereinstimmenden Dateien in diesem Verzeichnis und in allen Unterverzeichnissen globalisieren:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
In einigen Fällen, z. B. wenn sich die Dateinamen bereits in einer Datei befinden, müssen Sie möglicherweise Folgendes verwenden read
:
# IFS= makes sure it doesn't trim leading and trailing whitespace
# -r prevents interpretation of \ escapes.
while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
process "$line"
done < filename
read
kann sicher in Kombination mit verwendet find
werden, indem das Trennzeichen entsprechend eingestellt wird:
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
Für komplexere Suchvorgänge möchten Sie wahrscheinlich find
entweder die -exec
Option oder Folgendes verwenden -print0 | xargs -0
:
# execute `process` once for each file
find . -name \*.txt -exec process {} \;
# execute `process` once with all the files as arguments*:
find . -name \*.txt -exec process {} +
# using xargs*
find . -name \*.txt -print0 | xargs -0 process
# using xargs with arguments after each filename (implies one run per filename)
find . -name \*.txt -print0 | xargs -0 -I{} process {} argument
find
kann auch in das Verzeichnis jeder Datei kopiert werden, bevor ein Befehl mit -execdir
anstelle von ausgeführt wird -exec
, und kann interaktiv (Eingabeaufforderung vor Ausführung des Befehls für jede Datei) mit -ok
anstelle von -exec
(oder -okdir
anstelle von -execdir
) erstellt werden.
*: Technisch gesehen führen beide find
und xargs
(standardmäßig) den Befehl mit so vielen Argumenten aus, wie sie in die Befehlszeile passen, so oft, bis alle Dateien durchlaufen sind. In der Praxis spielt es keine Rolle, ob Sie über eine sehr große Anzahl von Dateien verfügen. Wenn Sie die Länge überschreiten, diese jedoch alle in derselben Befehlszeile benötigen, finden Sie bei SOL einen anderen Weg.