Mostrar todo el file hasta el partido

grep --before-context 5 muestra 5 líneas antes del partido.

Quiero mostrar todo antes del partido.
Hacer grep --before-context 99999999 funcionaría pero no es muy … profesional.

¿Cómo mostrar todo el file hasta la coincidencia?

Sed es mejor para eso.

Solo haz:

 sed '/PATTERN/q' FILE 

Funciona así:

Para cada línea, vemos si coincide con /PATTERN :

  • si es así, lo imprimimos y salimos
  • de lo contrario, lo imprimimos

Esta es la solución más eficiente, porque tan pronto como ve PATTERN , se cierra. Sin q , sed continuaría leyendo el rest del file y no haría nada con él. Para files grandes, puede marcar la diferencia.

Este truco también se puede usar para emular la head :

 sed 10q FILE 

sed puede replace la mayor parte de la funcionalidad de grep.

 sed -n '1,/<pattern>/ p' <file> 

Esto significa imprimir desde la primera línea hasta que coincida el patrón.

Un par de ejemplos de range

 sed -n '/<pattern>/,$ p' <file> # from pattern to end of file sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2 

imprimir hasta e incluyendo el partido:

 awk '{print} /pattern/ {exit}' filename sed '/pattern/q' filename 

imprime hasta PERO NO incluido el partido:

 awk '/pattern/ {exit} {print}' filename sed '/pattern/Q' filename 

Los siguientes methods puros de GNU grep no son eficientes.

Busque todo hasta la primera instancia de la cadena " foo " en la barra de files, usando tres grep s:

 grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar 

Coincidiendo hasta la última instancia de " foo ":

 grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar 

Nota: los detalles sobre el último grep se pueden encontrar en: Regex (grep) para la búsqueda de múltiples líneas necesaria .

Para personas como yo, que eligen recordar solo el uso básico de las herramientas y están dispuestos a aceptar soluciones less elegantes y less eficientes:

 head -n $(grep -n pattern filename | cut -d: -f1) filename 

También puede usar uno de los siguientes

 tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

o

 tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac 

o

 tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac 

La primera opción es muy similar a la sugerida por OP, pero se asegura de que muestre suficientes líneas antes del context contando las líneas en el file

La segunda opción busca el número de línea de la primera coincidencia (también podría cambiar eso cambiando la 'cabeza' interna) y luego usa la cabeza en ese número

La última opción reemplaza todas las líneas nuevas con la coincidencia y reemplaza dos coincidencias adyacentes con una nueva línea. El resultado de esto es una línea para cada bloque de text entre dos coincidencias. Después de eso, usa 'head' para elegir la primera línea (mwaning the block of text hasta el primer partido) match y luego vuelve a traducir cada coincidencia a una nueva línea. esta opción solo funciona si el file está en el siguiente formatting

 pattern texttexttext texttexttext texttexttext texttexttexttexttexttexttexttexttext pattern texttexttext pattern texttexttext texttexttexttexttexttexttexttexttext 

Etcétera