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 globstarOption 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
readkann sicher in Kombination mit verwendet findwerden, 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 findentweder die -execOption 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
findkann auch in das Verzeichnis jeder Datei kopiert werden, bevor ein Befehl mit -execdiranstelle von ausgeführt wird -exec, und kann interaktiv (Eingabeaufforderung vor Ausführung des Befehls für jede Datei) mit -okanstelle von -exec(oder -okdiranstelle von -execdir) erstellt werden.
*: Technisch gesehen führen beide findund 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.