Como posso procurar um padrão de múltiplas linhas em um arquivo?
-
02-07-2019 - |
Pergunta
Eu precisava encontrar todos os arquivos que continham um padrão seqüência específica. A primeira solução que vem à mente é usando encontrar encanada com xargs grep :
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'
Mas se eu preciso encontrar padrões que se estende sobre mais de uma linha, eu estou preso por causa de baunilha grep não consegue encontrar padrões de várias linhas.
Solução
Então eu descobri pcregrep que significa Perl Compatible regular Expressions GREP .
Por exemplo, você precisa encontrar arquivos onde o ' _name ' variável é immediatelly seguido pelo ' _DESCRIÇÃO ' variável:
find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'
Dica: você precisa incluir a linha de caráter pausa em seu padrão. Dependendo da sua plataforma, que poderia ser '\ n', \ r', '\ r \ n', ...
Outras dicas
Por que você não ir para awk :
awk '/Start pattern/,/End pattern/' filename
grep -P
também usa libpcre, mas é muito mais amplamente instalada. Para encontrar uma seção title
completa de um documento HTML, mesmo que se estende por várias linhas, você pode usar isto:
grep -P '(?s)<title>.*</title>' example.html
Desde implementa o projeto PCRE ao padrão perl, use a documentação perl para referência:
Aqui está um exemplo mais útil:
pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html
Ele procura a tag title em um arquivo html mesmo que se estende até 5 linhas.
Aqui está um exemplo de linhas ilimitadas:
pcregrep -Mi "(?s)<title>.*</title>" example.html
Com prata pesquisador :
ag 'abc.*(\n|.)*efg'
otimizações de velocidade de pesquisador prata poderia brilhar aqui.
Você pode usar a alternativa grep Sift aqui (disclaimer: Eu sou o autor).
Ele suporta correspondência de várias linhas e limitar a pesquisa a tipos específicos de arquivos fora da caixa:
sift -m --files '*.py' 'YOUR_PATTERN'
(procurar todos os arquivos * py para o padrão regex multilinha especificada)
Ele está disponível para todos os principais sistemas operacionais. Dê uma olhada na amostras para ver como ele pode ser usado para extrair várias linhas valores de um arquivo XML.
Esta resposta pode ser útil:
Regex (grep) para multi-line de pesquisa necessários
Para recursivamente você pode usar bandeiras -R (recursivo) e --include (GLOB padrão). Veja:
Use grep --exclude / - incluem sintaxe para não grep através de determinados arquivos
perl -ne 'print if (/begin pattern/../end pattern/)' filename
Usando ex
/ editor vi
e globstar opção (sintaxe semelhante à awk
e sed
):
ex +"/string1/,/string3/p" -R -scq! file.txt
onde aaa
é o seu ponto de partida, e bbb
é seu texto final.
Para procurar de forma recursiva, tente:
ex +"/aaa/,/bbb/p" -scq! **/*.py
. Observação: Para habilitar sintaxe **
, shopt -s globstar
run (Bash 4 ou zsh)
@Marcin: awk exemplo não ganancioso:
awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename