Es gibt keine Möglichkeit, dies nur mit sed zu tun. Sie müssen mindestens das Find-Dienstprogramm zusammen verwenden:
find . -type f -exec sed -i.bak "s/foo/bar/g" {} \;
Dieser Befehl erstellt einen .bak Datei für jede geänderte Datei.
Hinweise:
- Die
-iArgument fürsedcommand ist eine GNU-Erweiterung, wenn Sie also diesen Befehl mit demsedvon BSD ausführen Sie müssen die Ausgabe in eine neue Datei umleiten und sie dann umbenennen. - Die
findDienstprogramm implementiert nicht den-execArgument in alten UNIX-Boxen, also müssen Sie einen| xargsverwenden stattdessen.
Ich bevorzuge find | xargs cmd über find -exec weil es leichter zu merken ist.
Dieses Beispiel ersetzt "foo" global durch "bar" in .txt-Dateien in oder unter Ihrem aktuellen Verzeichnis:
find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/foo/bar/g"
Die -print0 und -0 Optionen können weggelassen werden, wenn Ihre Dateinamen keine seltsamen Zeichen wie Leerzeichen enthalten.
Für die Portabilität verlasse ich mich nicht auf Funktionen von sed, die spezifisch für Linux oder BSD sind. Stattdessen verwende ich die overwrite Skript aus dem Buch von Kernighan und Pike über die Unix-Programmierumgebung.
Der Befehl lautet dann
find /the/folder -type f -exec overwrite '{}' sed 's/old/new/g' {} ';'
Und die overwrite script (das ich überall verwende) ist
#!/bin/sh
# overwrite: copy standard input to output after EOF
# (final version)
# set -x
case $# in
0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2
esac
file=$1; shift
new=/tmp/$$.new; old=/tmp/$$.old
trap 'rm -f $new; exit 1' 1 2 15 # clean up files
if "[email protected]" >$new # collect input
then
cp $file $old # save original file
trap 'trap "" 1 2 15; cp $old $file # ignore signals
rm -f $new $old; exit 1' 1 2 15 # during restore
cp $new $file
else
echo "overwrite: $1 failed, $file unchanged" 1>&2
exit 1
fi
rm -f $new $old
Die Idee ist, dass eine Datei nur dann überschrieben wird, wenn ein Befehl erfolgreich ist. Nützlich in find und auch dort, wo Sie es nicht verwenden möchten
sed 's/old/new/g' file > file # THIS CODE DOES NOT WORK
da die Shell die Datei vor sed abschneidet kann es lesen.