Como posso excluir uma palavra com grep?


Respostas:


802

Você pode fazer isso usando -va --invert-matchopção (for ) do grep como:

grep -v "unwanted_word" file | grep XXXXXXXX

grep -v "unwanted_word" filefiltrará as linhas que possuem unwanted_worde grep XXXXXXXXlistará apenas as linhas com padrão XXXXXXXX.

EDITAR:

No seu comentário, parece que você deseja listar todas as linhas sem o unwanted_word. Nesse caso, tudo que você precisa é:

grep -v 'unwanted_word' file

2
e se eu quiser excluir N linhas após a linha com "palavra indesejada" também? -v 'unwanted_word' --after Nnão ajuda porque INCLUI a linha e N linhas depois.
Andrey Regentov 6/11/2014

-vou --invert-matchselecione linhas não correspondentes. No seu caso grep -v 'unwanted_word' fileou grep --invert-match 'unwanted_word' file.
Adamski.pro 29/11

Quero ignorar uma linha acima e uma linha abaixo com o padrão correspondente. Como posso alcançá-lo?
Kanji Viroja

Impressionante, eu uso isso no git para ler rapidamente o status do meu repo, funciona como um encanto: #git status -s |grep -v "folder_I_dont_care"
benjaminz

3
Estranho, é a resposta principal, mas em alguns casos está errado! Se eu quiser encontrar sun, exceto quando for sunrise, grep sun|grep -v sunrisepula a linha que contém os dois sune sunriseao mesmo tempo, não é isso que eu quero. grep -P 'sun(?!rise)'é muito melhor.
greene 24/03

86

Entendi a pergunta como "Como faço para corresponder uma palavra, mas excluir outra", para a qual uma solução são dois greps em série: primeiro grep encontrando a "palavra1" desejada, segundo grep excluindo "palavra2":

grep "word1" | grep -v "word2"

No meu caso: preciso diferenciar entre "plot" e "#plot", que a opção "word" do grep não funciona ("#" não é alfanumérico).

Espero que isto ajude.


16
Você deve reverter a ordem para obter destaque word1.
Matthew Leia

1
Eu acho que seria esclarecer a adição de um espaço reservado para o nome do arquivo para esse exemplo
patrick

39

Se você grepsuporta expressões regulares Perl com a -Popção que você pode fazer (se bash; se tcsh, você precisará escapar do !):

grep -P '(?!.*unwanted_word)keyword' file

Demo:

$ cat file
foo1
foo2
foo3
foo4
bar
baz

Vamos agora listar todos, fooexcetofoo3

$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$ 

Obrigado por isso, muito útil! Eu gostaria de mencionar que o comando grep é diferencia maiúsculas de minúsculas por padrão
DocWiki

2
Observe que grep -v -Ptambém funciona sem negação na expressão regular.
cybersoft

"se bash ... você precisará escapar do !" . Obrigado, obrigado, obrigado! Era isso que eu queria!
Gabriel Staples

36

A solução certa é usar grep -v "word" file, com seu awkequivalente:

awk '!/word/' file

No entanto, se você tiver uma situação mais complexa na qual deseja, por exemplo, XXXaparecer e YYY não aparecer, será awkútil em vez de canalizar vários greps:

awk '/XXX/ && !/YYY/' file
#    ^^^^^    ^^^^^^
# I want it      |
#            I don't want it

Você pode até dizer algo mais complexo. Por exemplo: eu quero aquelas linhas que contêm XXXou YYY, mas não ZZZ:

awk '(/XXX/ || /YYY/) && !/ZZZ/' file

etc.


2
Parece ser muito mais rápido que a grep -Psolução em arquivos grandes.
MBR

@MBR grep -Psignifica usar o Perl regexp, portanto, carregar esse pacote será muito mais caro do que o normal grep.
fedorqui 'SO stop prejudying'

10

Inverter correspondência usando grep -v:

grep -v "unwanted word" file pattern

6

O grep fornece a opção '-v' ou '--invert-match' para selecionar linhas não correspondentes.

por exemplo

grep -v 'unwanted_pattern' file_name

Isso exibirá todas as linhas do arquivo file_name, que não possui 'indesejados_padrão'.

Se você estiver pesquisando o padrão em vários arquivos dentro de uma pasta, poderá usar a opção de pesquisa recursiva da seguinte maneira

grep -r 'wanted_pattern' * | grep -v 'unwanted_pattern'

Aqui, o grep tentará listar todas as ocorrências de 'wanted_pattern' em todos os arquivos do diretório atual e passará para o segundo grep para filtrar o 'indesejado_pattern'. '|' - o pipe dirá ao shell para conectar a saída padrão do programa esquerdo (grep -r 'wanted_pattern' *) à entrada padrão do programa direito (grep -v 'unwanted_pattern').


4

A -vopção mostrará todas as linhas que não correspondem ao padrão.

grep -v ^unwanted_word

-5

Eu tenho um diretório com um monte de arquivos. Quero encontrar todos os arquivos que NÃO contêm a string "speedup", então usei com êxito o seguinte comando:

grep -iL speedup *

1
Na página do manual: "-L, --files-match-Suprime a saída normal; em vez disso, imprima o nome de cada arquivo de entrada do qual nenhuma saída seria impressa normalmente. A digitalização será interrompida na primeira correspondência. " (Ênfase por mim) Então cuidado com isso!
Xuiqzy
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.