Eu estou tentando construir uma pesquisa grep que procura por um termo, mas exclui as linhas que têm um segundo termo. Eu queria usar vários -e "pattern"
opções, mas isso não funcionou.
Aqui está um exemplo de um comando que eu tentei e a mensagem de erro que ele gerou.
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Parece-me que o -v
aplica-se a todos os termos / padrões de pesquisa. Como isso é executado, mas não inclui search term
nos resultados.
grep -i -E "search term" -ve "exclude term"
Respostas:
Para e expressões com grep você precisa de duas invocações:
Se os termos que você está procurando não forem expressões regulares, use a correspondência de cadeia fixa (
-F
) O que é mais rápido:fonte
De repente, invocando grep duas vezes, só há uma maneira de pensar nisso. Envolve Expressões regulares compatíveis com Perl (PCRE) e alguns bastante hacky asserções de olhar ao redor .
Procurar por foo excluindo correspondências que contenham Barra , você pode usar:
Veja como isso funciona:
(?!bar)
corresponde a qualquer coisa que não Barra sem consumir caracteres da string. Então.
consome um único caractere.^((?!bar).)*
repete o acima do início da string (^
) até ao final do mesmo ($
). Ele falhará sebar
é encontrado em qualquer ponto dado, desde(?!bar)
não vai corresponder.(?=^((?!bar).)*$)
garante que a string corresponda ao padrão anterior, sem consumir caracteres da string.foo
procura por foo como sempre.Eu encontrei este hack em Expressão regular para corresponder a string que não contém uma palavra? . Em Bart Kiers 'resposta , você pode encontrar uma explicação muito mais detalhada de como o look-ahead negativo opera.
fonte
Se você quiser fazer isso em um passo, você pode usar o awk ao invés do grep.
Formato:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Exemplos:
echo "hello there" | awk '/hello/ && !/there/'
Não retorna nada.
echo "hello thre" | awk '/hello/ && !/there/'
Retorna: olá lá
echo "hllo there" | awk '/hello/ && !/there/'
Não retorna nada.
Para vários padrões, você pode usar parênteses para agrupá-los.
Exemplos:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Retorna: olá lá
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Retorna: oi ai
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
Não retorna nada.
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
Não retorna nada.
fonte
ls --color=always | awk '/hello/ && !/goodbye/'
grep -R
em vários arquivos de código usando a linha de comando do Ubuntu.De minhas experiências, não parece fazer muita diferença se você canaliza seus termos de exclusão através
grep
oused
. Sed tem alguns outros recursos úteis de substituição de texto que eu costumo usar para filtrar melhor a saída de arquivos de log. Então eu vou usar o sed enquanto eu combino um grande número de filtros no sed.fonte
grep -F
ao invés degrep -E
e não use-i
se você não precisar.sed
;)