Como encontrar correspondências de padrão em várias linhas com grep

0
25


grep é um utilitário de pesquisa de texto de linha de comando que pode encontrar padrões e strings em arquivos e outros tipos de entrada. A maioria das correspondências corresponderá em apenas uma linha, mas geralmente é útil combinar várias novas linhas.

Correspondência em várias novas linhas com grep

Lidar com correspondências de várias linhas é algo grep tem dificuldade com. Uma ferramenta melhor para o trabalho é awk qualquer sed, que lidam com entrada de várias linhas naturalmente. Usar duas expressões com uma vírgula entre elas corresponderá a qualquer coisa entre esses dois padrões.

awk '/from/,/to/' file
sed -n '/from/,/to/p' file

Ainda é possível lidar com isso em grepno entanto, o comando é muito desajeitado.

grep -Pz '(?s)from.*n.*to' test

Isso faz algumas coisas:

  • -P Habilite a expressão regular compatível com Perl.
  • -z alimenta o arquivo inteiro como uma linha, com “zero bytes” em vez de uma nova linha. Isso permite que o grep processe tudo como uma única linha.
  • (?s) ativa PCRE_DOTALL, o que faz com que o . caractere corresponde a qualquer caractere, incluindo novas linhas.
  • from É a partida de abertura.
  • .*n.* vai combinar com tudo até toque é a partida final.

Geralmente, isso será feito para fins de script, mas é muito importante lembrar se você estiver escrevendo isso sozinho. Também, usando o -o a marcação para imprimir somente correspondência também imprimirá um caractere de zero byte à direita, o que pode causar problemas adicionais.

Use pcre2grep em vez disso (grep compatível com Perl)

Regular grep não é a melhor ferramenta para o trabalho, e existe uma alternativa chamada pcre2grep que inclui suporte para Expressões Regulares compatíveis com Perl, e é capaz de combinar Regex de várias linhas com muita facilidade.

Provavelmente está instalado no seu sistema, mas se não estiver, você pode obtê-lo no seu gerenciador de pacotes:

sudo apt install pcre2-utils

Então você só precisa executá-lo com o -M parâmetro.

pcre2grep -M 'from(n|.)*to' file

Observe que isso ainda exige que você combine “nova linha ou qualquer caractere” manualmente com (n|.)* . Alternativamente, você pode usar o (?s) truque para ativar PCRE_DOTALL e fazer com que o caractere ponto corresponda às novas linhas também.

pcre2grep -M '(?s)from.*to' file