una solución utilizando awk
:
awk '$0 ~ "XXXX" { lines2del = 5; nlines = 0; }
nlines == 5 { print lines[NR%5]; nlines-- }
lines2del == 0 { lines[NR%5] = $0; nlines++ }
lines2del > 0 { lines2del-- }
END { while (nlines-- > 0) { print lines[(NR - nlines) % 5] } }' fv.out
Actualización:
Este es el sc ript explicó:
- Recuerdo la última 5 líneas de la matriz
lines
mediante índices rotatorios (NR% 5; NR es el número de registro; en este caso líneas).
- Si encuentro el patrón en la línea actual (
$0 ~ "XXXX
; $0
siendo el registro actual: en este caso, una línea, y ~
ser el extendido de expresiones regulares operador de partido), que restablezca el número de líneas de lectura y nota que Tengo 5 líneas para eliminar (incluida la línea actual).
- Si ya leí 5 líneas, imprimo la línea actual.
- Si no tengo líneas para eliminar (lo cual también es cierto si he leído 5 líneas, pongo la línea actual en el búfer e incremento el número de líneas. Observe cómo el número de líneas se reduce y luego se incrementa si se imprime una línea.
- Si es necesario eliminar líneas, no imprimo nada y disminuyo el número de líneas para eliminar.
- Al final del guión, imprimo todas las líneas que están en la matriz.
Mi versión original del guión fue el siguiente, pero terminó la optimización a la versión anterior:
awk '$0 ~ "XXXX" { lines2del = 5; nlines = 0; }
lines2del == 0 && nlines == 5 { print lines[NR%5]; lines[NR%5] }
lines2del == 0 && nlines < 5 { lines[NR%5] = $0; nlines++ }
lines2del > 0 { lines2del-- }
END { while (nlines-- > 0) { print lines[(NR - nlines) % 5] } }' fv.out
awk
es una gran herramienta! Recomiendo encarecidamente que encuentres un tutorial en la red y lo leas. Una cosa importante: awk
funciona con Expresiones regulares extendidas (ERE). Su sintaxis es un poco diferente de Expresión regular estándar (RE) utilizada en sed
, pero todo lo que se puede hacer con RE se puede hacer con ERE.
Gracias, exactamente lo que estaba buscando (tengo las ocurrencias del patrón separadas por al menos 20 líneas). –