reemplazar examples comando bash sed solaris redirect

bash - examples - sed linux reemplazar



Redirigir la salida de sed ''s/c/d/'' myFile a myFile (10)

Estoy usando sed en una secuencia de comandos para hacer un reemplazo y quiero que el archivo reemplazado sobrescriba el archivo. Normalmente creo que usarías esto:

% sed -i ''s/cat/dog/'' manipulate sed: illegal option -- i

Sin embargo como puedes ver mi sed no tiene ese comando.

Intenté esto:

% sed ''s/cat/dog/'' manipulate > manipulate

Pero esto solo convierte la manipulación en un archivo vacío (tiene sentido).

Esto funciona:

% sed ''s/cat/dog/'' manipulate > tmp; mv tmp manipulate

Pero me preguntaba si había una forma estándar de redirigir la salida al mismo archivo del que se tomó la entrada.


Kernighan y Pike en la programación de The Art of Unix discuten este tema. Su solución es escribir un script llamado overwrite , que permite hacer tales cosas.

El uso es: overwrite file cmd .

# overwrite: copy standard input to output after EOF opath=$PATH PATH=/bin:/usr/bin case $# in 0|1) echo ''Usage: overwrite file cmd [args]'' 1>&2; exit 2 esac file=$1; shift new=/tmp/overwr1.$$; old=/tmp/overwr2.$$ trap ''rm -f $new $old; exit 1'' 1 2 15 # clean up if PATH=$opath "$@" >$new then cp $file $old # save original trap '''' 1 2 15 # wr are commmitted cp $new $file else echo "overwrite: $1 failed, $file unchanged" 1>&2 exit 1 fi rm -f $new $old

Una vez que tenga el script anterior en su $PATH , puede hacer:

overwrite manipulate sed ''s/cat/dog/'' manipulate

Para hacer su vida más fácil, puede usar replace script del mismo libro:

# replace: replace str1 in files with str2 in place PATH=/bin:/usr/bin case $# in 0|2) echo ''Usage: replace str1 str2 files'' 1>&2; exit 1 esac left="$1"; right="$2"; shift; shift for i do overwrite $i sed "s@$left@$right@g" $i done

Tener replace en su $PATH también le permitirá decir:

replace cat dog manipulate


Muchas respuestas, pero ninguna de ellas es correcta. Aquí está el correcto y el más simple:

$ echo "111 222 333" > file.txt $ sed -i -s s/222/444/ file.txt $ cat file.txt 111 444 333 $


Normalmente uso la tercera vía, pero con un cambio importante :

$ sed ''s/cat/dog/'' manipulate > tmp && mv tmp manipulate

Es decir cambio a && así que el movimiento solo sucede si sed tiene éxito; de lo contrario, perderá su archivo original tan pronto como cometa un error tipográfico en su sintaxis sed.

¡Nota! Para aquellos que leen el título y pierden la restricción del OP "my sed no admite -i " : para la mayoría de las personas, sed admitirá -i , por lo que la mejor manera de hacerlo es:

$ sed -i ''s/cat/dog/'' manipulate


Para cambiar varios archivos (y guardar una copia de seguridad de cada uno como * .bak):

perl -p -i -e "s / oldtext / newtext / g" *

replaces any occurence of oldtext by newtext in all files in the current folder. However you will have to escape all perl special characters within oldtext and newtext using the backslash This is called a “Perl pie” (mnemonic: easy as a pie) The -i flag tells it do do in-place replacement, and it should be ok to use single (“''”) as well as double (“””) quotes. If using ./* instead of just *, you should be able to do it in all sub-directories See man perlrun for more details, including how to take a backup file of the original. using sed: sed -i ''s/old/new/g'' ./* (used in GNU) sed -i '''' ''s/old/new/g'' ./* (used in FreeBSD)


Puede utilizar sponge de los moreutils .

sed "s/cat/dog/" manipulate | sponge manipulate


Quizás -i sea ​​gnu sed, o simplemente una versión antigua de sed, pero de todos modos. Estás en el camino correcto. La primera opción es probablemente la más común, la tercera opción es si desea que funcione en todas partes (incluidas las máquinas solaris) ... :) Estas son las formas "estándar" de hacerlo.


Sí, -i también es compatible con FreeBSD / MacOSX sed , pero necesita la cadena vacía como argumento para editar un archivo en el lugar.

sed -i "" ''s/old/new/g'' file # FreeBSD sed


Si no desea mover las copias, puede usar ed:

ed file.txt <<EOF %s/cat/dog/ wq EOF


Solución utilizando los manejadores de archivos abiertos:

exec 3<manipulate

Evita que el archivo abierto sea truncado:

rm manipulate sed ''s/cat/dog/'' <&3 > manipulate


-i opción -i no está disponible en sed estándar.

Tus alternativas son tu tercera vía o perl .