Exclua arquivos com conteúdo específico

Exclua arquivos com conteúdo específico

Tendo milhares de arquivos de dados (mesma extensão) em um diretório, como deletar aqueles que contêm uma instrução de parâmetro específica?

Por exemplo, se eu fosse deletar todos os arquivos contendo a linha

Key = 0

eu poderia fazer algo como

grep -i "Key = 0" * | rm *

Responder1

Você pode usar o seguinte comando no shell. Isso deve funcionar se o padrão a ser pesquisado forKey = 0

grep -lrIZ "Key = 0" . | xargs -0 rm -f --

Comando genérico:

grep -lrIZ "<Pattern to be searched in the file>" . | xargs -0 rm -f --

Responder2

O principal problema com o pipeline usando grep+ rmé que ele rmnão lê seu fluxo de entrada padrão, o que significa que ele não lê nada do grepcomando no lado esquerdo do pipe.

Em vez disso, o rm *lado direito do canal ignoraria todas as entradas e executaria rmem todos os nomes de arquivo visíveis no diretório atual.

Ignorando o problema de rmnão ler sua entrada padrão, seu grepcomando tem dois problemas principais:

  1. Ele gera linhas correspondentes com nomes de arquivos. Isso seria inútil, rmpois precisamos saberapenasos nomes dos arquivos que queremos excluir.
  2. Corresponde Key = 0como umsubstring, o que significa que também corresponde Crypto Key = 0x01etc.

find . -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +

ou, com GNU find(e alguns outros),

find . -type f -exec grep -q -F -x 'Key = 0' {} \; -delete

Ambos procurariam arquivos regulares no diretório atual ou abaixo e, para cada arquivo encontrado, executariam grep -q -F -x 'Key = 0'. Este grepcomando retornaria um status de saída sinalizando se existe uma linha no arquivo que estáexatamente Key = 0(e nada mais).

O segundo findcomando excluirá o arquivo usando seu -deletepredicado se tal linha for encontrada. O primeiro findcomando coletaria os nomes dos caminhos dos arquivos que contêm esta linha e depois seria executado rm -fem lotes deles.

As bandeiras usadas grepsão

  • -q, para operação silenciosa. O utilitário não gera linhas correspondentes, mas sai com êxito após a primeira correspondência ou com um status de saída diferente de zero se o arquivo não contiver uma correspondência.
  • -F, para correspondência de string fixa. Estamos combinando com uma string, não com uma expressão regular.
  • -x, para encontrar apenas correspondências de linha completa. Isso tem o mesmo efeito de usar uma expressão regular ancorada no início e no final da linha.

Não estou usando -iaqui grep, pois isso também excluiria arquivos contendo linhas como KEY = 0e kEY = 0etc., e você não disse nada sobre essas variações de caso.

Você deseja que o findcomando seja restrito a um sufixo de nome de arquivo específico, como e .ext, em seguida, use -name '*.ext'no findcomando antes da execução de grep. Por exemplo:

find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +

informação relacionada