Tengo un archivo como el siguiente.
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
~PAR2~
This is Par2 line 1
This is Par2 line 2
Par Finished
Si paso PAR1
, debería obtener todas las líneas entre PAR1
y Par Finished
la línea. ¿Cómo puedo obtenerlo? Estuve investigando awk
y sed
no encontré ninguna opción.
Respuesta1
Si desea la línea de encabezado y pie de página, entonces es bastante simple con sed
, por ejemplo,
sed -n "/^~PAR1~$/,/Par Finished/p"
Esto es fácil de usar con una variable.
START=PAR1
sed -n "/^~$START~$/,/Par Finished/p"
También podemos hacer que la última línea sea una variable.
START=PAR1
END="Par Finished"
sed -n "/^~$START~$/,/$END/p"
El resultado se parece a:
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Ahora bien, si no desea las líneas de inicio/final y no desea la línea en blanco, entonces es un poco más complicado.
Puede que haya mejores formas, pero esta funciona para mí:
sed -n "/^~$START~$/,/$END/ { /^~$START~$/d ; /$END/d ; /^$/d ; p }"
El resultado de esto es
This is Par1 line 1
This is Par1 line 2
Respuesta2
Puede usar la Par Finished
línea (con líneas en blanco al final opcionales) como separador de registros (y luego reemplazarla para completar el registro)
awk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {print $0,"\nPar Finished"}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Si tiene GNU
awk, puede recuperar el separador de registros con la variable especial RT
(eliminando las nuevas líneas adicionales si lo desea)
gawk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {sub("\n*$", "", RT); print $0,RT}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Por supuesto, si no necesitas aprobar unvariable Par1
usas un rango de expresiones regulares simple
awk '/PAR1/,/Par Finished/' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Respuesta3
Con grep
y pcre
para entrada de archivos suficientemente pequeños
$ s="PAR1"
$ grep -oPz "(?s)[^\n]*${s}.*?\n.*?Par Finished.*?\n" ip.txt
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Para obtener líneas entre el patrón:
$ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par Terminado)" ip.txt Este es el Par1 línea 1 Este es el Par1 línea 2
Cambiando variable aPAR2
$s="PAR2" $ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par finalizado)" ip.txt Este es el Par2 línea 1 Este es el Par2 línea 2
Referencia: Regex (grep) para búsqueda de varias líneas