Wenden Sie einen Befehl rekursiv an, um alle Dateien in einem Verzeichnis zu ändern

Wenden Sie einen Befehl rekursiv an, um alle Dateien in einem Verzeichnis zu ändern

Ich habe einen Befehl, der eine Datei liest und eine geänderte Version ausgibt stdout:

./convert /path/to/file

Wie kann ich diesen Befehl rekursiv auf alle Dateien in einem Verzeichnis anwenden undüberschreibt den vorhandenen Inhalt jeder Datei mit dem Ergebnis des obigen Befehls?

ich fanddiese FrageDas ist sehr ähnlich, aber alle angebotenen Lösungen beinhalten die Ausgabe der Ergebnisse in eine einzelne Datei, was ich nicht möchte.

Antwort1

Wenn ich das richtig verstehe, können Sie eine Datei konvertieren mit

./convert /path/to/file >/path/to/file.new
mv /path/to/file.new /path/to/file

Um einen Befehl auf jede Datei in einem Verzeichnisbaum anzuwenden, verwenden Sie denfindDienstprogramm. Da Sie für jede Datei einen komplexen Befehl ausführen müssen, müssen Sie explizit eine Shell aufrufen.

find /path/to/top/directory -type f -exec sh -c '
  /path/to/convert "$0" >"$0.new" &&
  mv "$0.new" "$0"
' {} \;

Antwort2

Die Frage, auf die Sie verlinkt haben, funktioniert nicht rekursiv, sondern nur eine Ebene tief. Verwenden Sie für die Rekursion find:

find . -type f -exec /path/to/convert {} \;

convertSie möchten sich selbst aus dem Baum herausbewegen, durch den Sie gehen, da dies das Risiko birgt, dass es versucht, sich selbst zu ändern.

Antwort3

Wenn ich das richtig verstehe, möchten Sie jede Eingabedatei mit dem Ergebnis convertdieser Eingabedatei überschreiben. Wenn ja, versuchen Sie Folgendes:

find . -type f | while IFS= read -r file; do
  ./convert "$file" > /tmp/foo.tmp && mv /tmp/foo.tmp "$file";
done

Antwort4

Ausgeliehen von @Gilles' exzellentemAntwort:

find /path/to/top/directory -type f -exec sh -c '/path/to/convert "$0" | tee "$0"' {} \;

Ich habe das oben genannte mit versucht sed, es hat funktioniert.

verwandte Informationen