sed
Sustitución
Buscar..
Sustitución usando variables de shell
Las variables dentro de comillas simples '
no se expanden con shells compatibles con POSIX, por lo que usar una variable de shell en una sustitución sed
requiere el uso de comillas dobles "
lugar de comillas simples '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Tenga cuidado con la inyección de comandos al evaluar las variables:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Si se ejecutara lo anterior como raíz, la salida no se habría podido distinguir del primer ejemplo y el contenido de /etc/passwd
se destruiría.
Referencia inversa
Usando corchetes escapados, puede definir un grupo de captura en un patrón que puede ser referenciado en la cadena de sustitución con \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
Con múltiples grupos:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
Cuando se usan expresiones regulares extendidas (ver Opciones adicionales ), los paréntesis realizan la agrupación de forma predeterminada y no tienen que escaparse:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Las palabras que consisten en letras, dígitos y guiones bajos pueden combinarse utilizando la expresión [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
La secuencia \w
es equivalente a [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Usando diferentes delimitadores.
La especificación de base de grupo abierto POSIX / IEEE dice :
[2addr] s / BRE / replacement / flags
Sustituya la cadena de reemplazo por instancias de BRE en el espacio del patrón. Se puede usar cualquier carácter que no sea barra invertida o nueva línea en lugar de una barra inclinada para delimitar el BRE y el reemplazo. Dentro del BRE y el reemplazo, el delimitador BRE se puede usar como un carácter literal si está precedido por una barra invertida.
Hay casos en que el delimitador /
para el reemplazo de sed
está en el BRE o el reemplazo, lo que desencadena errores como:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
Para esto, podemos usar diferentes delimitadores como #
o _
o incluso un espacio:
$ echo "2/3/4" | sed "s#2/3#X#"
X/4
$ echo "2/3/4" | sed "s_2/3_X_"
X/4
$ echo "2/3/4" | sed "s 2/3 X "
X/4
Banderas de patrón - reemplazo de ocurrencia
Si queremos reemplazar solo la primera aparición en una línea, usamos sed
como siempre:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Pero ¿y si queremos reemplazar todas las ocurrencias?
Acabamos de añadir la bandera del patrón g
al final:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
Y si queremos reemplazar una ocurrencia específica, podemos especificar cuál:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
siendo la tercera ocurrencia.
De info sed
, vea el manual de GNU sed para la versión en línea
El estándar POSIX no especifica lo que debería suceder cuando mezcla los modificadores
g
NUMBER, y actualmente no existe un significado ampliamente aceptado en todas las implementacionessed
. Para GNUsed
, la interacción se define como: ignorar las coincidencias antes del NUMBERth, y luego coincidir y reemplazar todas las coincidencias desde el NUMBERth en adelante.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd