
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 grep
operadores lógicos.
O uso de múltiplas
-e
opções corresponde a qualquer coisa que corresponda a qualquer um dos padrões, dando aoOUOperação.Exemplo:
grep -e pattern1 -e pattern2 filename
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
grep -v
pode simular oNÃOOperação.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 awk
você 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 grep
comandos 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 -E
opção de OR e -v
de negação.
Seu exemplo específico é bastante desagradável e provavelmente se beneficiaria com algum utilitário mais poderoso (veja a resposta de @muru).