Se vuoi l'equivalente di sed -i.bak
, è piuttosto semplice.
Considera questo script per GNU sed:
#!/bin/sh
# Create an input file to demonstrate
trap 'rm -r "$dir"' EXIT
dir=$(mktemp -d)
grep -v '[[:upper:][:punct:]]' /usr/share/dict/words | head >"$dir/foo"
# sed program - removes 'aardvark' and 'aardvarks'
script='/aard/d'
##########
# What we want to do
sed -i.bak -e "$script" "$dir"
##########
# Prove that it worked
ls "$dir"
cat "$dir/foo"
Possiamo semplicemente sostituire la linea contrassegnata con
cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"
Questo sposta il file esistente in un backup e scrive un nuovo file.
Se vogliamo l'equivalente di
sed -i -e "$script" "$dir" # no backup
allora è leggermente più complesso. Possiamo aprire il file per la lettura come input standard, quindi scollegarlo, prima di dirigere l'output di sed per sostituirlo:
( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )
Lo facciamo in una sub-shell, in modo che il nostro stdin originale sia ancora disponibile dopo questo. È possibile cambiare input e tornare indietro senza una subshell, ma in questo modo mi sembra più chiaro.
Nota che stiamo attenti a copiare prima, piuttosto che creare un nuovo foo
file: questo è importante se il file è noto con più di un nome (cioè ha collegamenti fissi) e vuoi essere sicuro di non interrompere i collegamenti .
/usr/gnu/bin/sed
per ottenere il supporto -i.