Befehl wie dieser:
find /directory -type f -name "*.txt" -print | xargs rm
löscht jede .txt
Datei im Verzeichnis und den Unterverzeichnissen, und das ist ok. Aber wenn wir eine Variable oder ein Array für die Dateierweiterung erstellen und dann find
z. B.
TXT=(*.txt)
for ii in ${TXT[@]}; do
find /directory -type f -name $TXT -print | xargs rm
done
Diese Befehle löschen keine .txt
Dateien in Unterverzeichnissen. Warum? Wie kann ich diesen zweiten Code ändern, um Dateien in Unterverzeichnissen zu löschen?
PS: Ich habe ein Array verwendet, weil ich mehr als eine Dateierweiterung habe.
Antwort1
Ihre Array-Zuordnung,
TXT=(*.txt)
erweitert das *.txt
Muster auf die Liste der Dateinamen im aktuellen Verzeichnis, die diesem Muster entsprechen. Die Shell würde dies zum Zeitpunkt der Zuweisung tun. Das ist nicht das, was Sie wollen. Sie möchten find
den wörtlichen String *.txt
wie folgt angeben:
pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +
Hier habe ich auch entfernt xargs rm
und führe stattdessen rm
direkt von aus find
. Die meisten aktuellen Implementierungen von könnten anstelle von find
das nicht standardmäßige verwenden :-delete
-exec rm {} +
pattern='*.txt'
find /directory -type f -name "$pattern" -delete
Beachten Sie, dass hier keine Schleife erforderlich ist, da wir nur mit einem einzigen Muster arbeiten. Beachten Sie auch, dass die Anführungszeichen "$pattern"
im Aufruf von find
wichtig sind, da das Muster sonst vor dem Start durch alle passenden Dateinamen im aktuellen Verzeichnis ersetzt würde find
.
Für verschiedene Muster könnten Sie eine Schleife wie folgt ausführen:
patterns=( '*.txt' '*.tmp' )
for pattern in "${patterns[@]}"; do
find /directory -type f -name "$pattern" -delete
done
Die Anführungszeichen in der Array-Zuweisung sind wichtig, da sie verhindern, dass die Shell die Muster sofort als Muster zum Globbing von Dateinamen verwendet. Aus demselben Grund sind auch die Anführungszeichen von "${patterns[@]}"
und wichtig."$pattern"
Ein anderer Ansatz besteht darin, nur einen einzigen Aufruf von durchzuführen find
, selbst wenn Sie mehrere Muster haben. Dies würde die Dinge erheblich beschleunigen, wenn es /directory
sich um eine große Verzeichnishierarchie handelt. Der folgende Code tut dies, indem er ein Array von -name
Tests für erstellt, die find
verwendet werden sollen:
patterns=( '*.txt' '*.tmp' )
name_tests=( )
for pattern in "${patterns[@]}"; do
name_tests+=( -o -name "$pattern" )
done
# "${name_tests[@]:1}" removes the initial "-o", which shouldn't be there.
name_tests=( '(' "${name_tests[@]:1}" ')' )
find /directory -type f "${name_tests[@]}" -delete
Im obigen Skript wird am Ende der eigentliche Befehl ausgeführt:
find /directory -type f '(' -name '*.txt' -o -name '*.tmp' ')' -delete
... wodurch alle regulären Dateien mit Dateinamensuffixen gelöscht werden.txt
oder .tmp
irgendwo im oder unterhalb des Verzeichnisses /directory
.