grep com operadores lógicos


19

Existe um utilitário semelhante ao grep que me permitirá fazer pesquisas grep com operadores lógicos. Quero poder aninhar e combinar as construções lógicas livremente. Por exemplo, coisas como essa devem ser possíveis:

grep (term1 && term2) || (term1 && (term3 xor term4)) *

Sei que isso pode ser feito com vanilla grep e scripts adicionais do bash, mas meu objetivo aqui é evitar a necessidade de fazer isso.

grep 

Respostas:


12

Com awk, assim como com perl, você terá que incluir termos //, mas isso pode ser feito:

awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))' 

28

Existem várias maneiras de usar grepcom operadores lógicos.

  1. Use \|para separar vários padrões para a condição OU .

    Exemplo: grep 'pattern1\|pattern2' filename

  2. Use a -Eopção para enviar vários padrões para a condição OU .

    Exemplo: grep -E 'pattern1|pattern2' filename

  3. O uso de uma única -ecorresponde a apenas um padrão, mas o uso de várias -eopções corresponde a mais de um padrão.

    Exemplo: grep -e pattern1 -e pattern2 filename

  4. grep -vpode simular a operação NOT .

  5. Não existe um operador ANDgrep , mas você pode simular a força bruta AND usando a -Eopção

    Exemplo: grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    O exemplo acima corresponde a todas as linhas que contêm tanto Pattern1 e pattern2 em qualquer ordem.)


1
-Enão é completamente equivalente a &&devido ao fato de que ele é sensível fim-
Iruvar

grep foo | grep baré uma maneira mais geral de fazer AND.
Kenster

2
+1 por explicar claramente que não existe um operador "AND" real e que o melhor que podemos fazer é simular um hack usando uma estrutura OR. Obviamente, isso ficará complicado com mais de três termos, mas por dois termos funciona bem.
precisa saber é o seguinte

grep -c -e MATCH1 -e MATCH2 é ótimo quando você está interessado na contagem de nomes de arquivos.
andrej 10/07

4

Você pode usar perl:

perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'

0
sed '/term1/!d;/term2/b' -e '/term3/!d;/term4/d' *

Eu acredito que realiza o que você está tentando fazer. Ele delimina da saída qualquer linha que não corresponda term1, bsai do script (e assim imprime automaticamente) qualquer linha que permanece e que corresponde term2, e para as linhas que permanecem exclui qualquer que não corresponda term3e daquelas que não correspondem term4.

sed Os scripts são avaliados em ordem e todos os testes são booleanos; portanto, qualquer ação resultante de um teste afetará diretamente o comportamento das ações a seguir.


0

Eu uso para encadear grepcomandos para obter um AND lógico:

grep expr1 filename | grep expr2

Eu acredito que é bem direto, semelhante ao Unix e elegante.


Então você pode combinar (como o @Tushi explicou detalhadamente) com a -Eopção para OR-ing e -vnegar.

Seu exemplo específico é bastante desagradável e provavelmente se beneficiaria de algum utilitário mais poderoso (consulte a resposta do @ muru).

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.