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.

tuxnani
fonte
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 
arash kordi
fonte
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.

nullrevolution
fonte
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

rubystallion
fonte
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.
Manikandan Rajendran
fonte
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.

Kenorb
fonte
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
2

acabei de encontrar

grep $'\r'

É usado $'\r'para escape no estilo C no Bash.

no presente artigo

HHHartmann
fonte