Si quieres el equivalente de sed -i.bak
, es bastante simple.
Considere este script para 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"
Simplemente podemos reemplazar la línea marcada con
cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"
Esto mueve el archivo existente para que sea una copia de seguridad y escribe un nuevo archivo.
Si queremos el equivalente de
sed -i -e "$script" "$dir" # no backup
entonces es un poco más complejo. Podemos abrir el archivo para leerlo como entrada estándar, luego desvincularlo, antes de dirigir la salida de sed para reemplazarlo:
( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )
Hacemos esto en un sub-shell, para que nuestro stdin original todavía esté disponible después de esto. Es posible cambiar las entradas y volver sin un subshell, pero de esta manera me parece más claro.
Tenga en cuenta que tenemos cuidado de copiar primero, en lugar de crear un nuevo foo
archivo; esto es importante si el archivo se conoce por más de un nombre (es decir, tiene enlaces duros) y desea asegurarse de no romper los enlaces .
/usr/gnu/bin/sed
para obtener soporte -i.