La forma portátil de hacer esto, y la forma más eficiente, es con direcciones. Puedes hacerlo:
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
De esta manera, si la línea no contiene el gato de cadena y no contiene los rangos del perro de cadena sed
b
fuera de la secuencia de comandos, imprime automáticamente su línea actual y tira de la siguiente para comenzar el siguiente ciclo. Por lo tanto, no realiza la siguiente instrucción, que en este ejemplo c
cuelga toda la línea para leer Bear pero podría hacer cualquier cosa.
Probablemente valga la pena señalar también que cualquier instrucción que siga al comando !b
en ese sed
comando solo puede coincidir en una línea que contenga la cadena dog
o cat
, por lo que puede realizar más pruebas sin peligro de coincidir con una línea que no lo hace, lo que significa que ahora puede aplicar reglas solo a uno u otro también.
Pero eso es lo siguiente. Aquí está la salida del comando anterior:
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
También puede implementar de forma portátil una tabla de búsqueda con referencias posteriores.
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x
};G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'
Es mucho más trabajo configurarlo para este caso de ejemplo simple, pero puede hacer sed
scripts mucho más flexibles a largo plazo.
En la primera línea, x
cambio el espacio de espera y el espacio de patrón, luego inserto el perro <space>
gato de<space>
<space>
cuerda en el espacio de espera antes de x
volver a cambiarlos.
De ahí en adelante y en cada línea siguiente, mantengo el G
espacio agregado al espacio del patrón, luego verifico si todos los caracteres desde el comienzo de la línea hasta la nueva línea que acabo de agregar al final coinciden con una cadena rodeada de espacios después. Si es así, reemplazo todo el lote con Bear y, si no, no hay ningún daño porque la próxima vez que llevo P
solo hasta la primera línea nueva en el espacio del patrón, d
elijo todo.
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Y cuando digo flexible, lo digo en serio. Aquí está reemplazando el gato con BrownBear y el perro con BlackBear :
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x
};G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'
###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear
Por supuesto, puede ampliar mucho el contenido de la tabla de búsqueda: tomé la idea de los correos electrónicos de Usenet de Greg Ubben sobre el tema cuando, en los años 90, describió cómo construyó una calculadora cruda a partir de una sola sed s///
declaración.
-r
opción como sinónimo de-E
la compatibilidad con sed de GNU. OpenBSD y OS Xsed -E
interpretarán la tubería escapada como una tubería literal, no como un operador de alternancia. Aquí hay un enlace de trabajo a la página de manual de NetBSD y aquí hay uno para OpenBSD que no tiene diez años.