![Exclua arquivos com conteúdo específico](https://rvso.com/image/178487/Exclua%20arquivos%20com%20conte%C3%BAdo%20espec%C3%ADfico.png)
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 rm
não lê seu fluxo de entrada padrão, o que significa que ele não lê nada do grep
comando no lado esquerdo do pipe.
Em vez disso, o rm *
lado direito do canal ignoraria todas as entradas e executaria rm
em todos os nomes de arquivo visíveis no diretório atual.
Ignorando o problema de rm
não ler sua entrada padrão, seu grep
comando tem dois problemas principais:
- Ele gera linhas correspondentes com nomes de arquivos. Isso seria inútil,
rm
pois precisamos saberapenasos nomes dos arquivos que queremos excluir. - Corresponde
Key = 0
como umsubstring, o que significa que também correspondeCrypto Key = 0x01
etc.
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 grep
comando retornaria um status de saída sinalizando se existe uma linha no arquivo que estáexatamente Key = 0
(e nada mais).
O segundo find
comando excluirá o arquivo usando seu -delete
predicado se tal linha for encontrada. O primeiro find
comando coletaria os nomes dos caminhos dos arquivos que contêm esta linha e depois seria executado rm -f
em lotes deles.
As bandeiras usadas grep
sã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 -i
aqui grep
, pois isso também excluiria arquivos contendo linhas como KEY = 0
e kEY = 0
etc., e você não disse nada sobre essas variações de caso.
Você deseja que o find
comando seja restrito a um sufixo de nome de arquivo específico, como e .ext
, em seguida, use -name '*.ext'
no find
comando antes da execução de grep
. Por exemplo:
find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +