No Linux, como posso encontrar todos os arquivos que contêm uma string e excluí-los?

15

Desejo excluir todos os arquivos que contenham a string foo . Como posso fazer isso usando o bash no Linux?

    
por Kitsos 20.04.2013 / 17:44

3 respostas

31

Aqui está uma maneira segura:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l imprime os nomes dos arquivos que correspondem ao padrão de pesquisa.
  • -r realiza uma pesquisa recursiva para o padrão foo no diretório fornecido . . Se isso não funcionar, tente -R .
  • -I (capital i ) faz com que arquivos binários, como PDFs, sejam ignorados.
  • -Z garante que os nomes dos arquivos sejam zero- (isto é, nul-) terminados, de modo que um nome contendo espaço em branco não seja interpretado de maneira errada (ou seja, como vários nomes em vez de um).
  • xargs -0 alimenta os nomes dos arquivos de grep a rm -f , separando palavras por zero (nul) bytes (lembre-se da opção -Z de grep ).
  • -- é frequentemente esquecido, mas é muito importante marcar o final das opções e permitir a remoção de arquivos cujos nomes começam com - .

Se você quiser ver quais arquivos estão prestes a serem excluídos, basta remover a parte | xargs -0 rm -f -- e deixar a opção Z em grep .

Outro usuário sugeriu algo como o seguinte, que você não deve executar porque não é seguro:

files='grep foo * | cut -d: -f1'
rm -f $files         # unsafe, do not run it!

Se eu tiver arquivos ImportantStuff que não desejo excluir e obsolete ImportantStuff contendo foo , perco ImportantStuff (e não obsolete ImportantStuff !) quando eu corro este comando, porque $files é quebrado em espaços quando é interpretado. É perigoso colocar uma lista de nomes de arquivos em uma variável de shell escalar dessa maneira.

    
por 20.04.2013 / 19:17
17
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

Isso recursivamente procura arquivos contendo foo . O segundo -exec só será executado se o primeiro exec sair com êxito, ou seja, se grep corresponder. Dryrun e remova o echo se a saída parecer correta.

Ou alternativamente

$ find -type f -exec grep -q "foo" {} \; -print

e

$ find -type f -exec grep -q "foo" {} \; -delete

como sugerido por Lekensteyn.

    
por 20.04.2013 / 17:59
1

Eu faria o que Adrian diz,

Mas eu adicionaria limites de palavras ao foo para não apagar acidentalmente arquivos que continham "comida" (a menos que esteja excluindo tudo o que contém comida, é o que você quer.)

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

acutamente, eu redirecionaria a saída antes de excluir, para poder revisar antes de excluir:

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete
    
por 21.04.2013 / 09:44