two strings patterns shell unix sed awk pattern-matching

shell - strings - awk between two patterns



Cómo seleccionar líneas entre dos patrones de marcador que pueden aparecer varias veces con awk/sed (8)

De los enlaces de la respuesta anterior, el que lo hizo por mí, ejecutando ksh en Solaris, fue este:

sed ''1,/firstmatch/d;/secondmatch/,$d''

Usando awk o sed ¿cómo puedo seleccionar líneas que están ocurriendo entre dos patrones de marcador diferentes? Puede haber varias secciones marcadas con estos patrones.

Por ejemplo: supongamos que el archivo contiene:

abc def1 ghi1 jkl1 mno abc def2 ghi2 jkl2 mno pqr stu

Y el patrón inicial es abc y el patrón final es mno Entonces, necesito la salida como:

def1 ghi1 jkl1 def2 ghi2 jkl2

Estoy usando sed para que coincida con el patrón una vez:

sed -e ''1,/abc/d'' -e ''/mno/,$d'' <FILE>

¿Hay alguna manera en sed o awk de hacerlo repetidamente hasta el final del archivo?


Esto podría funcionar para usted (GNU sed):

sed ''/^abc$/,/^mno$/{//!b};d'' file

Borre todas las líneas excepto aquellas entre las líneas que comienzan abc y mno



Usando sed :

sed -n -e ''/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }''

La opción -n significa que no se imprime por defecto.

El patrón busca líneas que contengan solo abc a solo mno , y luego ejecuta las acciones en { ... } . La primera acción borra la línea abc ; el segundo, la línea mno ; y la p imprime las líneas restantes. Puede relajar las expresiones regulares según sea necesario. Cualquier línea fuera del rango de abc .. mno simplemente no se imprime.


Use awk con una bandera para activar la impresión cuando sea necesario:

$ awk ''/abc/{flag=1;next}/mno/{flag=0}flag'' file def1 ghi1 jkl1 def2 ghi2 jkl2

¿Como funciona esto?

  • /abc/ coincide con las líneas que tienen este texto, así como /mno/ does.
  • /abc/{flag=1;next} establece el flag cuando se encuentra el texto abc . Entonces, se salta la línea.
  • /mno/{flag=0} desata la flag cuando se encuentra el texto mno .
  • El flag final es un patrón con la acción predeterminada, que es print $0 : si el flag es igual a 1, se imprime la línea.

Para obtener una descripción y ejemplos más detallados, junto con los casos en que los patrones se muestran o no, consulte ¿Cómo seleccionar líneas entre dos patrones? .


algo como esto funciona para mí:

file.awk:

BEGIN { record=0 } /^abc$/ { record=1 } /^mno$/ { record=0; print "s="s; s="" } !/^abc|mno$/ { if (record==1) { s = s"/n"$0 } }

usando: awk -f file.awk data ...

editar: la solución O_o fedorqui es mucho mejor / más bonita que la mía.


perl -lne ''print if((/abc/../mno/) && !(/abc/||/mno/))'' your_file


sed ''/^abc$/,/^mno$/!d;//d'' file

golfs dos personajes mejor que ppotong''s {//!b};d

Las barras diagonales vacías // significan: "reutilizar la última expresión regular utilizada". y el comando hace lo mismo que el más comprensible:

sed ''/^abc$/,/^mno$/!d;/^abc$/d;/^mno$/d'' file

Esto parece ser POSIX :

Si un RE está vacío (es decir, no se especifica ningún patrón) sed se comportará como si se hubiera especificado el último RE utilizado en el último comando aplicado (ya sea como una dirección o como parte de un comando sustituto).