Como fornecer um padrão para uma nova linha no grep?


98

Como fornecer um padrão para uma nova linha no grep? Nova linha no início, nova linha no final. Não é a forma de expressão regular. Algo como \ n.


6
Não está claro o que você deseja. new line at the beginningé uma linha em branco e new line at endse aplica a todas as linhas do arquivo. Você pode postar um exemplo?
PP

3
Na verdade, você pode apenas usar $. É um pouco limitado, mas pode ser usado em casos simples.
Krzysztof Jabłoński

Respostas:


86

grep os padrões são combinados com linhas individuais, portanto, não há como um padrão corresponder a uma nova linha encontrada na entrada.

No entanto, você pode encontrar linhas vazias como esta:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 

Pelo menos GNU grep tem a opção -z que faz o grep quebrar as linhas por caracteres nulos. No entanto, não parece suportar nova linha ou \ n no padrão para corresponder à nova linha, consulte o relatório de bug .
jarno

1
@jarno Suporta \ n em padrões com o sinalizador -P
rubystallion

92

tente em pcregrepvez de regular grep:

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

a -Mopção permite a correspondência em várias linhas, para que você possa pesquisar por novas linhas como \n.


23

Graças a @jarno eu conheço a opção -z e descobri que ao usar GNU grep com a opção -P, é possível fazer a correspondência\n . :)

Exemplo:

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

Impressões bar


1
Ótimo, observe que não recebo notificação sobre o "@jarno" na resposta.
jarno

3
Isso é ótimo! Muito obrigado por compartilhar!
Alicia Tang,

Funciona para mim. Muito obrigado. grep -zoPnir "dex\n035" ./dir/
galian

22

Você pode usar desta forma ...

grep -P '^\s$' file
  • -Pé usado para expressões regulares Perl (uma extensão para POSIX grep).
  • \scorresponder aos caracteres de espaço em branco; se seguido por *, também corresponde a uma linha vazia.
  • ^corresponde ao início da linha. $corresponde ao fim da linha.

2
-Pé uma extensão GNU. Posso usá-lo quando a situação exigir (normalmente lookahead / lookbehind), mas POSIX grep pode fazer isso apenas com o arquivo [[:space:]].
Jordânia,

1
As páginas de manual grep de FWIW, Solaris e BSD (não checou outras) têm um parágrafo para -P. GNU é bastante padrão de qualquer maneira. :)
K3 --- rnc

1
Da página de manual: [-P] Esta opção não é suportada no FreeBSD.
Marián Černý

Não [-P] para MacOsX: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e padrão] [-f arquivo] [--binary-files = value] [--color [= quando]] [--colour [= quando]] [--context [= num]] [--label] [--line-buffered] [--null] [padrão] [arquivo. ..]
Niccolò

@ Niccolò Você desejará brew install grepobter o GNU grep, que é superior em vários aspectos. apple.stackexchange.com/questions/193288/…
herdrick

6

Quanto à solução alternativa (sem usar não portátil -P), você pode substituir temporariamente um caractere de nova linha por um diferente e alterá-lo novamente, por exemplo:

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

Basicamente, ele está procurando uma correspondência exata _foo_onde _significa \n(então __= \n\n). Você não precisa traduzi-lo de volta por tr '_' '\n', já que cada padrão seria impresso na nova linha de qualquer maneira, então removê-lo _é suficiente.


perdoe minha ignorância, mas o uso de substituição de processo ainda não é outro NON compatível com posix, portanto, um recurso não portátil? em posix shell eu não poderia fazer <(p paste -sd_ file )?
humanidade e

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.