grep com operadores lógicos

grep com operadores lógicos

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 esta deveriam ser possíveis:

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

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

Responder1

Existem muitas maneiras de usar grepoperadores lógicos.

  1. O uso de múltiplas -eopções corresponde a qualquer coisa que corresponda a qualquer um dos padrões, dando aoOUOperação.

    Exemplo:grep -e pattern1 -e pattern2 filename

  2. Em expressões regulares estendidas ( grep -E), você pode usar |para combinar vários padrões com oOUOperação.

    Exemplo: grep -E 'pattern1|pattern2' filename

  3. grep -vpode simular oNÃOOperação.

  4. Não háEoperador in grep, mas você pode simular com força brutaEusando vários padrões com |.

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

    O exemplo acima irá corresponder a todas as linhas que contêm ambos padrão1epadrão2em qualquer ordem. Isso fica muito feio se houver mais padrões para combinar.

Responder2

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

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

Observe que xor()o que é uma extensão GNU não padrão é bit a bit xor, não lógico. Tudo bem aqui, pois eles /regex/retornam apenas 0 ou 1.

Com other awkvocê pode definir uma lógica xor()como uma função:

function xor(a, b) {
  return (a || b && ! (a && b))
}

Ou

function xor(a, b) {
  return ((a && !b) || (b && !a))
}

Responder3

Você poderia usar perl:

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

Onde ocomutasão como segue:

-w turns on warnings
-n runs perl against each line of input (looping)
-e executes perl passed in the command line

Responder4

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

grep expr1 filename | grep expr2

Eu acredito que é bastante simples, semelhante ao Unix e elegante.


Então você pode combinar (como @Tushi explicou detalhadamente) com a -Eopção de OR e -vde negação.

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

informação relacionada