Ich erstelle ein Skript, das Dateien mithilfe der Konfiguration löscht, die Ordner und Dateipräfix enthält.
Dies wird die Konfigurationsdatei sein:
config.txt
/local/FolderA,App /local/FolderB,Log /local/FolderC,File
Dies ist mein Skript:
file="local/config.txt" while IFS="," read -r folder prefix; do find %s -name %s* -type f -exec rm {} \ "$folder" "$prefix"; done < "$file"
Es funktioniert jedoch nicht richtig. Können Sie bei der Fehlerbehebung helfen? Ich habe Probleme beim Zuweisen der Werte aus IFS
dem Befehl.
Antwort1
Angenommen, Ihre Konfigurationsdatei enthält keine Felder mit eingebetteten Zeilenumbrüchen oder Kommas und angenommen, Sie möchten alle Dateien mit dem genannten Dateinamenpräfix nur in den angegebenen Verzeichnissen löschen (also nicht rekursiv):
#!/bin/sh
while IFS=, read -r directory prefix; do
rm -- "$directory/$prefix"*
done <config.txt
Dies liest das erste durch Kommas getrennte Feld jeder Zeile in die directory
Variable und den Rest der Zeile in die prefix
Variable. Anschließend werden diese zum Löschen der Dateien verwendet. (SieheWo ist das Argument „--“ (Doppelstrich) dokumentiert?für eine Erklärung zu --
)
Wenn Sie die Löschung rekursiv durchführen müssen, geben Sie unter jedem genannten Verzeichnispfad Folgendes ein:
#!/bin/sh
while IFS=, read -r directory prefix; do
find "$directory" -name "$prefix*" -exec rm {} +
done <config.txt
Der Unterschied zwischen diesen beiden besteht, abgesehen von find
der rekursiven Suche, darin, dass es $prefix
so verwendet wird, als wäre es ein Globbing-Muster im find
Befehl.
Beachten Sie, dass *
in Anführungszeichen gesetzt werden muss, wenn es mit verwendet wird, find
damit die Shell es nicht auf übereinstimmende Namen im aktuellen Verzeichnis erweitert, und das *
sollte seinnicht zitiertbei Verwendung mit rm
in der ersten Schleife oben, sodass die Shell es auf alle passenden Namen erweitert.
Wenn dunichtSie möchten die Löschung rekursiv durchführen, haben aber so viele Dateien, die den generierten Mustern entsprechen, dass die erste Schleife den Fehler „Argumentliste zu lang“ ausgibt. Dann möchten Sie möglicherweise eine zusätzliche innere Schleife ausführen.
#!/bin/sh
while IFS=, read -r directory prefix; do
for pathname in "$directory/$prefix"*; do
rm -- "$pathname"
done
done <config.txt
oder die Nutzung find
beschränkt auf den Suchpfad der obersten Ebene,
#!/bin/sh
while IFS=, read -r directory prefix; do
find "$directory" ! -path "$directory" -prune -name "$prefix*" -exec rm {} +
done <config.txt
Antwort2
Wir verwenden xargs, um Dateipfade aus der Datei config.txt an eine ausführbare Sh-Datei in ihrer Befehlszeile zu übergeben.
< config.txt xargs -rd'\n' sh -c '
for arg do
find "${arg%,*}" \
-name "${arg##*,}*" \
-type f \
-exec rm -f {} + ;
done
' xargs-sh