Gostaria de obter a correspondência de vários padrões com AND implícito entre padrões, ou seja, equivalente à execução de vários greps em uma sequência:
grep pattern1 | grep pattern2 | ...
Então, como convertê-lo em algo como?
grep pattern1 & pattern2 & pattern3
Eu gostaria de usar o grep único porque estou criando argumentos dinamicamente, para que tudo tenha que caber em uma sequência. Usar filtro é um recurso do sistema, não um grep, portanto não é um argumento para isso.
Não confunda esta pergunta com:
grep "pattern1\|pattern2\|..."
Esta é uma correspondência de vários padrões OU .
grep
regular-expression
greenoldman
fonte
fonte
Respostas:
agrep
pode fazer isso com esta sintaxe:Com o GNU
grep
, quando criado com suporte para PCRE, você pode:Com ast
grep
:(adicionando
.*
s como<x>&<y>
casa cadeias que correspondem tanto<x>
e<y>
exatamente ,a&b
nunca correspondem como não há tal string que pode ser tantoa
eb
ao mesmo tempo).Se os padrões não se sobrepuserem, você também poderá:
A melhor maneira portátil é provavelmente
awk
como já mencionado:Com
sed
:Lembre-se de que todos terão sintaxe de expressão regular diferente.
fonte
agrep
sintaxe não está funcionando para mim ... em qual versão foi introduzida?agrep
podem ser encontradas incluídas no glimpse / webglimpse . Possivelmente você tem uma implementação diferente. No entanto, tive um erro na versão ast-grep, a opção para regexps aumentados é-X
, não-A
.agrep
0.8.0 no Fedora 23. Parece ser diferente doagrep
que você mencionou.agrep
.awk '/p1/ && /p2/ {n++}; END {print 0+n}'
Você não especificou a versão grep, isso é importante. Alguns mecanismos regexp permitem várias correspondências agrupadas por AND usando '&', mas esse é um recurso não padrão e não portátil. Mas, pelo menos, o GNU grep não suporta isso.
OTOH, você pode simplesmente substituir grep por sed, awk, perl, etc. (listados em ordem de aumento de peso). Com awk, o comando pareceria
e pode ser construído para ser especificado na linha de comando de maneira fácil.
fonte
awk
usa EREs, por exemplo, o equivalente agrep -E
, em oposição aos BREs que a planíciegrep
usa.awk
As expressões regulares são chamadas de EREs, mas na verdade são um pouco idiossincráticas. Provavelmente, existem mais detalhes do que qualquer um se importa: wiki.alpinelinux.org/wiki/Regexawk
- simplesmente saber mais é melhor).{ print; }
peça não seja realmente necessária ou útil aqui.Se
patterns
contiver um padrão por linha, você poderá fazer algo assim:Ou isso corresponde a substrings em vez de expressões regulares:
Para imprimir todos em vez de há linhas de entrada no caso que
patterns
está vazio, substituaNR==FNR
comFILENAME==ARGV[1]
, ou comARGIND==1
nogawk
.Essas funções imprimem as linhas de STDIN que contêm cada sequência especificada como argumento como uma substring.
ga
significa grep all egai
ignora case.fonte
Essa não é uma solução muito boa, mas ilustra um "truque" bem legal
fonte
chained-grep()
oufunction chained-grep
nãofunction chained-grep()
: unix.stackexchange.com/questions/73750/…git grep
Aqui está a sintaxe usando a
git grep
combinação de vários padrões usando expressões booleanas :O comando acima imprimirá linhas correspondentes a todos os padrões de uma só vez.
Procure
man git-grep
ajuda.Veja também:
Para operação OR , consulte:
fonte
ripgrep
Aqui está o exemplo usando
rg
:É uma das ferramentas de grepping mais rápidas, pois é construída sobre o mecanismo de expressão regular da Rust, que usa autômatos finitos, SIMD e otimizações literais agressivas para tornar a pesquisa muito rápida.
Consulte também solicitação de recurso relacionado no GH-875 .
fonte
Aqui está minha opinião, e isso funciona para palavras em várias linhas:
Use
find . -type f
seguido por tantas-exec grep -q 'first_word' {} \;
e a última palavra-chave com
-exec grep -l 'nth_word' {} \;
-q
-l
arquivos de exibição silenciosos / silenciososA seguinte lista de nomes de arquivos com as palavras 'rabbit' e 'hole':
find . -type f -exec grep -q 'rabbit' {} \; -exec grep -l 'hole' {} \;
fonte
Para encontrar TODAS as palavras (ou padrões), você pode executar o grep no loop FOR . A principal vantagem aqui é pesquisar a partir de uma lista de regexs .
EDITE minha resposta com um exemplo real:
Agora vamos executá-lo neste arquivo:
fonte
ALL
operador, seu código funciona comoOR
operador, nãoAND
. E aliás. pois that (OR
) é uma solução muito mais fácil, dada diretamente na pergunta.AND
operador, o que significa que o arquivo é apenas um resultado positivo se corresponder ao padrão A e o padrão B e padrão C e ...AND
No seu caso, o arquivo será positivo se corresponder padrão A ou padrão B ou ... Você vê a diferença agora?AND
-los. Então você deve reescrever o script para executar em vários arquivos - então talvez você perceba que a pergunta já foi respondida e sua tentativa não traz nada à mesa, desculpe.