Jeśli chcesz ekwiwalent sed -i.bak
, jest to dość proste.
Rozważ ten skrypt dla 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"
Możemy po prostu zamienić zaznaczoną linię na
cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"
To przenosi istniejący plik jako kopię zapasową i zapisuje nowy plik.
Jeśli chcemy odpowiednika
sed -i -e "$script" "$dir" # no backup
to jest nieco bardziej złożone. Możemy otworzyć plik do odczytu jako standardowe wejście, a następnie rozłączyć go, zanim wydamy polecenie sed w celu zastąpienia:
( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )
Robimy to w podpowłoce, aby nasz oryginalny stdin był nadal dostępny po tym. Możliwe jest przełączanie wejść i przełączanie z powrotem bez podpowłoki, ale ten sposób wydaje mi się jaśniejszy.
Pamiętaj, że staramy się najpierw skopiować, a nie utworzyć nowy foo
plik - jest to ważne, jeśli plik jest znany pod więcej niż jedną nazwą (tzn. Ma twarde linki) i chcesz mieć pewność, że nie zerwiesz linków .
/usr/gnu/bin/sed
aby uzyskać obsługę -i.