¿Cómo dar un patrón para una nueva línea en grep?

95

¿Cómo dar un patrón para una nueva línea en grep? Nueva línea al principio, nueva línea al final. No es la forma de expresión regular. Algo como \ n.

tuxnani
fuente
6
No está claro lo que quieres. new line at the beginninges una línea en blanco y se new line at endaplica a todas las líneas del archivo. Puede publicar un ejemplo?
PP
2
De hecho, puedes usar $. Es algo limitado, pero se puede utilizar en casos sencillos.
Krzysztof Jabłoński

Respuestas:

84

grep los patrones se comparan con líneas individuales por lo que no hay forma de que un patrón coincida con una nueva línea encontrada en la entrada.

Sin embargo, puede encontrar líneas vacías como esta:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 
arash kordi
fuente
Al menos GNU grep tiene la opción -z que hace que grep divida las líneas por carácter nulo. Sin embargo, no parece admitir la nueva línea o \ n en el patrón para coincidir con la nueva línea, consulte el informe de error .
jarno
1
@jarno Admite \ n en patrones con la bandera -P
rubystallion
92

intente en pcregreplugar de regular grep:

pcregrep -M "pattern1.*\n.*pattern2" filename

la -Mopción le permite coincidir en varias líneas, por lo que puede buscar nuevas líneas como \n.

nula revolución
fuente
22

Puedes usar de esta manera ...

grep -P '^\s$' file
  • -Pse utiliza para expresiones regulares de Perl (una extensión de POSIX grep).
  • \scoincidir con los caracteres de espacio en blanco; si le sigue *, también coincide con una línea vacía.
  • ^coincide con el comienzo de la línea. $coincide con el final de la línea.
Manikandan Rajendran
fuente
2
-Pes una extensión GNU. Estoy bien para usarlo cuando la situación lo requiere (generalmente mirar hacia adelante / mirar hacia atrás), pero POSIX grep puede hacer esto solo con el archivo [[:space:]].
Jordanm
1
Las páginas de manual grep de FWIW, Solaris y BSD (no verificaron otras) tienen un párrafo para -P. GNU es bastante estándar de todos modos. :)
K3 --- rnc
1
Desde la página de manual: [-P] Esta opción no es compatible con FreeBSD.
Marián Černý
Tampoco [-P] para MacOsX: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e patrón] [-f archivo] [--binary-files = value] [--color [= cuando]] [--colour [= cuando]] [--context [= num]] [--label] [--line-búfer] [--null] [patrón] [archivo. ..]
Niccolò
@ Niccolò Querrás brew install grepobtener GNU grep, que es superior en varios aspectos. apple.stackexchange.com/questions/193288/…
herdrick
19

Gracias a @jarno, conozco la opción -z y descubrí que cuando se usa GNU grep con la opción -P, es posible realizar coincidencias\n . :)

Ejemplo:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

Huellas dactilares bar

semental rubí
fuente
1
Genial, tenga en cuenta que no recibo una notificación sobre el "@jarno" en la respuesta.
jarno
3
¡Esto es genial! ¡Muchas gracias por compartir!
Alicia Tang
6

En cuanto a la solución alternativa (sin usar no portátil -P), puede reemplazar temporalmente un carácter de nueva línea por otro diferente y volver a cambiarlo, por ejemplo:

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

Básicamente, busca una coincidencia exacta _foo_donde _significa \n(entonces __= \n\n). No tiene que volver a traducirlo tr '_' '\n', ya que cada patrón se imprimiría en la nueva línea de todos modos, por lo que eliminarlo _es suficiente.

Kenorb
fuente
disculpe mi ignorancia, pero ¿el uso de la sustitución de procesos no es otra característica NO compatible con posix, por lo tanto, no portátil? en posix shell que no pude hacer <(p paste -sd_ file )?
humanidad y
2

Se acaba de encontrar

grep $'\r'

Se usa $'\r'para escapar al estilo C en Bash.

en este articulo

HHHartmann
fuente