Como posso excluir recursivamente todos os arquivos de uma extensão específica no diretório atual?

531

Como excluo com segurança todos os arquivos com uma extensão específica (por exemplo .bak) do diretório atual e de todas as subpastas usando uma linha de comando? Simplesmente, tenho medo de usá-lo, rmpois o usei errado uma vez e agora preciso de conselhos.

user216038
fonte

Respostas:

840

Você nem precisa usar rmneste caso se tiver medo. Use find:

find . -name "*.bak" -type f -delete

Mas use-o com precaução. Execute primeiro:

find . -name "*.bak" -type f

para ver exatamente quais arquivos você removerá.

Além disso, verifique se esse -deleteé o último argumento em seu comando. Se você colocá-lo antes do -name *.bak argument, ele excluirá tudo .

Veja man finde man rmpara mais informações e veja também esta pergunta relacionada no SE:

Radu Rădeanu
fonte
Como isso é diferente rm *.bak?
sayantankhan
10
@ Bolt64 O seu rm *.baknão funcionará para subdiretórios.
Radu Rădeanu
Com as configurações padrão rm *.bak, somente os arquivos que terminam com .bak são excluídos no diretório atual. Para também fazer coisas em subdiretórios, você precisa mexer nos globs, usar a opção -r ou o exemplo de localização.
Hennes
9
@Hennes Tenha cuidado com rm -r *.bak! Ele também remove os diretórios que terminam .bakcom todo o seu conteúdo.
Radu Rădeanu
37
Verifique se esse -deleteé o último argumento em seu comando. Se você o colocar antes do -name *.bakargumento, ele excluirá tudo.
Michael
40
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
lokers
fonte
1
Bem-vindo ao askubuntu! Embora esta seja uma resposta perfeitamente válida, acho que não há nenhuma vantagem em usar isso em vez da -deletebandeira de find. Mais informações podem ser encontradas na entrada de manuais GNU para excluir arquivos com o find .
amigos estão dizendo sobre glutanimato
2
você provavelmente está certo, é apenas uma solução alternativa, talvez mais cru;)
lokers
11
Esta não é apenas uma alternativa, mas um exemplo de como outros comandos podem ser combinados com o pipe '|'. +1
Boris Pavlović
13
Estas soluções alternativas trabalhar em outros ambientes que não possuem -delete (como cygwin)
ciriarte
2
Eu acho que esta é a melhor resposta aqui.
Léo Léopold Hertz,
33

Primeiro, execute o comando shopt -s globstar. Você pode executar isso na linha de comando, e isso terá efeito apenas nessa janela do shell. Você pode colocá-lo no seu .bashrce, em seguida, todos os shells recém-iniciados o buscarão. O efeito desse comando é tornar **/os arquivos de correspondência no diretório atual e em seus subdiretórios recursivamente (por padrão, **/significa o mesmo que */: somente nos subdiretórios imediatos). Então:

rm **/*.bak

(ou gvfs-trash **/*.bakou o que você tem).

Gilles
fonte
21

Excluir arquivos não é para mim algo para o qual você deve usar rm. Aqui está uma alternativa:

sudo apt-get install gvfs     # install a tool that allows you to put stuff in the trash
alias "trash"="gvfs-trash"    # you can also put this in .bash_aliases or simply use the command without alias
trash *.bak                   # trash the files (thus moving them to the trash bin)

Como afirma Flimm nos comentários:

O pacote trash-clifaz a mesma coisa que gvfs-trashsem a dependência do gvfs.

Assim:

sudo apt-get install trash-cli

Você não precisa criar um alias para isso, porque o trash-clipacote fornece um comando trash, que faz o que queremos.

Como Eliah Kagan deixa claro em extensos comentários, você também pode fazer esse uso recursivo find. Nesse caso, você não pode usar um alias; portanto, os comandos abaixo assumem que você instalou trash-cli. Resumo os comentários de Eliah:

Este comando localiza e exibe todos os .bakarquivos e links simbólicos em qualquer lugar do diretório atual ou de seus subdiretórios ou abaixo.

find . -name '*.bak' -xtype f

Para excluí-los, adicione um -execcom o trashcomando:

find . -name '*.bak' -xtype f -exec trash {} +

-xtype fseleciona arquivos e links simbólicos para arquivos, mas não pastas. Para excluir também pastas .bak, remova essa parte e use -execdir, o que evita cannot trash non-existenterros de .bakarquivos dentro de .bakdiretórios:

find . -name '*.bak' -execdir trash {} +
don.joey
fonte
4
"Não use rmpara excluir coisas" é uma declaração controversa, mas eu tenho que concordar que geralmente é mais sábio usar algo que permita desfazer as coisas.
Oli
2
O pacote trash-clifaz a mesma coisa que gvfs-trashsem a dependência gvfs.
Flimm
Eu o editei na resposta, da próxima vez, sinta-se à vontade para fazer a edição.
don.joey
@ don.joey Esta resposta parece indicar o find . -name "*.bak" -type fque trash *.bakexclui. É isso mesmo o que você quer dizer? Você pode mover diretórios para a lixeira com trashou gvfs-trash, mas trash *.baksomente move arquivos e diretórios cujos nomes terminam com .bake que residem imediatamente no diretório atual. O shell se expande e *.bak, portanto trash *.bak, não afeta os .bakarquivos nos subdiretórios que não são nomeados .bak.
Eliah Kagan 14/10
1
@ don.joey Sim ls *.bak(o que eu acho que você quer dizer) lista os trash *.baktrashes. find . -name '*.bak' -xtype f -exec trash {} +trash todos os .bakarquivos em qualquer lugar abaixo .. Ele não pode usar um alias; portanto, instale trash-cliou escreva gvfs-trash. Aqui está um exemplo. -xtype fseleciona arquivos e links simbólicos para arquivos, mas não pastas. Para excluir .bak pastas também, use find . -name '*.bak' -execdir trash {} +, o que evita cannot trash non existenterros de .bakarquivos dentro de .bakdiretórios. Por favor, sinta-se à vontade para usar isso na sua resposta.
Eliah Kagan 14/10
5

Se você deseja excluir todos os arquivos de um determinado tipo, mas apenas 1 pasta "profunda" da pasta atual:

find . -maxdepth 2 -name "*.log" -type f -delete

-maxdepth 2 porque o diretório atual " . " conta como a primeira pasta.

Hipócrito
fonte
1

Resposta rápida:

  • Exclua todos os arquivos com o nome considerado ou o postfix recursivamente:

    find . -name '*.pyc' -type f -delete

  • Exclua todos os diretórios com o nome considerado recursivamente:

    find ~ -path '*/__pycache__/*' -delete‍‍‍
    find ~ -type d -name '__pycache__' -empty -delete‍‍‍
    

    Um pouco menos rigidamente controlado, mas em uma única linha:

    find ~ -path '*/__pycache__*' -delete
    

[ NOTA ]:

dé a opção de diretório e fé a opção de arquivo.

Benyamin Jafari
fonte
0

Se você estiver dentro de um repositório git, poderá usar:

git clean -fdx

Isso exclui arquivos e arquivos não rastreados no .gitignore.

Vasantha Ganesh K
fonte