GNU/Linux >> Tutoriales Linux >  >> Linux

Imprima líneas entre el patrón inicial y final, pero si el patrón final no existe, no imprima

Puede lograr esto de la siguiente manera:

$ sed -e '
    /BEGIN/,/END/!d
    H;/BEGIN/h;/END/!d;g
' inp

Cómo funciona es que, para el rango de líneas de inicio/fin, las almacena en el espacio de espera. Luego borra hasta que encuentres la línea END. En ese momento recordamos lo que está en espera. OTW, no sacamos nada.HTH.


cat input |
sed '/\*\*\*\*\* BEGIN \*\*\*\*\*/,/\*\*\*\*\* END *\*\*\*\*/ p;d' | 
tac |
sed '/\*\*\*\*\* END \*\*\*\*\*/,/\*\*\*\*\* BEGIN *\*\*\*\*/ p;d' |
tac

Funciona al tener tac invertir las líneas para que sed puede encontrar ambos delimitadores en ambos órdenes.


Con pcregrep :

pcregrep -M '(?s)BEGIN.*?END'

Eso también funciona si BEGIN y END están en la misma línea, pero no en casos como:

BEGIN 1 END foo BEGIN 2
END

Donde pcregrep atrapa el primer BEGIN 1 END , pero no el segundo.

Para manejarlos, con awk , podrías hacer:

awk '
  !inside {
    if (match($0, /^.*BEGIN/)) {
      inside = 1
      remembered = substr($0, 1, RLENGTH)
      $0 = substr($0, RLENGTH + 1)
    } else next
  }
  {
    if (match($0, /^.*END/)) {
      print remembered $0
      if (substr($0, RLENGTH+1) ~ /BEGIN/)
        remembered = ""
      else
        inside = 0
    } else
      remembered = remembered $0 ORS
  }'

En una entrada como:

a
BEGIN blah END BEGIN 1
2
END
b
BEGIN foo END
c
BEGIN
bar
END BEGIN
baz END
d
BEGIN
xxx

Da:

BEGIN blah END BEGIN 1
2
END
BEGIN foo END
BEGIN
bar
END BEGIN
baz END

Ambos necesitan almacenar todo, desde BEGIN hasta el siguiente END en la memoria. Entonces, si tiene un archivo enorme cuya primera línea contiene BEGIN pero sin FIN, todo el archivo se almacenará en la memoria sin costo alguno.

La única forma de evitarlo sería procesar el archivo dos veces, pero, por supuesto, eso solo se puede hacer cuando la entrada es un archivo normal (no una canalización, por ejemplo).


Linux
  1. Linux:copie y cree el directorio de destino si no existe

  2. Agregar una línea a un archivo solo si aún no existe

  3. ¿Por qué Tomcat funciona con el puerto 8080 pero no con el 80?

  4. El punto de montaje no existe, a pesar de haberlo creado

  5. Eliminar archivos que comienzan con pero no contienen

¿Por qué la expresión regular funciona en X pero no en Y?

¿Imprimir líneas entre (y excluyendo) dos patrones?

¿Imprimir líneas entre (e incluyendo) dos patrones?

¿Cómo unir líneas que no comienzan con "#" o ";"?

Linux – ¿Por qué Locale Es_mx funciona pero no Es?

Linux:¿/sbin/init no existe?