Así es como hacer una coincidencia no codiciosa de cadenas de caracteres múltiples usando sed. Digamos que desea cambiar cada foo...bar
a, <foo...bar>
por ejemplo, esta entrada:
$ cat file
ABC foo DEF bar GHI foo KLM bar NOP foo QRS bar TUV
debería convertirse en esta salida:
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
Para hacer eso, convierte foo y bar en caracteres individuales y luego usa la negación de esos caracteres entre ellos:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/g; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
En lo anterior:
s/@/@A/g; s/{/@B/g; s/}/@C/g
se está convirtiendo {
y }
a cadenas de marcador de posición que no pueden existir en la entrada para que esos caracteres estén disponibles para convertir foo
y bar
a.
s/foo/{/g; s/bar/}/g
es convertir foo
y bar
a {
y }
respectivamente
s/{[^{}]*}/<&>/g
está realizando la operación que queremos: convertir foo...bar
a<foo...bar>
s/}/bar/g; s/{/foo/g
está convirtiendo {
y de }
vuelta a foo
y bar
.
s/@C/}/g; s/@B/{/g; s/@A/@/g
está convirtiendo las cadenas de marcador de posición a sus caracteres originales.
Tenga en cuenta que lo anterior no se basa en que ninguna cadena particular no esté presente en la entrada, ya que fabrica tales cadenas en el primer paso, ni le importa qué ocurrencia de una expresión regular particular que desee hacer coincidir, ya que puede usar {[^{}]*}
tantas veces como sea necesario en la expresión para aislar la coincidencia real que desea y / o con el operador de coincidencia numérica seds, por ejemplo, para reemplazar solo la segunda aparición:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/2; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC foo DEF bar GHI <foo KLM bar> NOP foo QRS bar TUV