So lesen Sie Token aus einer Eingabedatei, um dort erwähnte Dateien zu löschen

So lesen Sie Token aus einer Eingabedatei, um dort erwähnte Dateien zu löschen

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 IFSdem 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 directoryVariable und den Rest der Zeile in die prefixVariable. 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 findder rekursiven Suche, darin, dass es $prefixso verwendet wird, als wäre es ein Globbing-Muster im findBefehl.

Beachten Sie, dass *in Anführungszeichen gesetzt werden muss, wenn es mit verwendet wird, finddamit die Shell es nicht auf übereinstimmende Namen im aktuellen Verzeichnis erweitert, und das *sollte seinnicht zitiertbei Verwendung mit rmin 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 findbeschrä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

verwandte Informationen