Encontre e exclua todos os diretórios denominados "test" no linux

35

Eu tenho muitos diretórios chamados "teste" e gostaria de removê-los.

Eu sei como encontrá-los e imprimi-los usando:

find . -name test -print

Agora, como faço para remover os diretórios?


Observe que eu também tenho arquivos no diretório e eles devem ser removidos.

coleta de lixo
fonte

Respostas:

70

xargs faz toda a mágica:

find . -name test -type d -print0|xargs -0 rm -r --

xargs executa o comando passado como parâmetros, com os argumentos passados ​​para stdin.

Isso está sendo usado rm -rpara excluir o diretório e todos os seus filhos.

O --indica o final dos argumentos, para evitar um caminho que começa com -de ser tratado como um argumento.

-print0diz findpara imprimir \0caracteres em vez de novas linhas; e -0diz xargspara tratar apenas \0como separador de argumentos.

Isso está chamando rmcom muitos diretórios ao mesmo tempo, evitando a sobrecarga de chamar rmseparadamente para cada diretório.


Como alternativa, findtambém pode executar um comando para cada arquivo selecionado :

find . -name test -type d -exec rm -r {} \;

E este, com melhor desempenho, pois chamará rmcom vários diretórios ao mesmo tempo :

find . -name test -type d -exec rm -r {} +

(Observe +no final; este é equivalente à xargssolução.)

Arnaud Le Blanc
fonte
11
Excelente resposta, especialmente a +em encontrar. Eu não tinha ideia, definitivamente desejava ter sabido disso há muito tempo.
Scott
atente para o último comando, de alguma forma ele excluiu alguns arquivos. o xargscomando funcionou bem.
Henrique de Sousa
23
find /path/to/dir -name "test" -type d -delete
  • -name: procura o nome passado. Você pode usar -regexpara fornecer nomes com base em expressões regulares

  • -type: procura por tipos de arquivo. dprocura apenas diretórios

  • -delete: ação que exclui a lista encontrada.

Alternativamente:

find /path/to/dir -name "test" -type d -exec rm -rf {} \;

Como JF Sebastian afirmou nos comentários:

Você pode usar em +vez de \;passar mais de um diretório por vez.

jaypal singh
fonte
11
Desculpe, esqueci de mencionar que esses diretórios podem ter arquivos. Não pude excluir alguns deles por causa do erro "localizar: não consigo excluir` ./start ': o diretório não está vazio "
coleta de lixo
@garbagecollection Adicionei uma atualização.
Jaypal singh
3
você pode usar em +vez de \;passar mais de um diretório por vez.
JFS
Obrigado @JFSebastian Bom ponto. Vou adicioná-lo à resposta.
Jaypal singh
5

Você também pode usar a opção -exec

find . -name test -exec rm {} \;
sethi
fonte
3

Assumindo bash 4+

shopt -s globstar
rm -r ./**/test/

A barra final significa que corresponderá apenas aos diretórios. O teste é antecipado com:

printf '%s\n' ./**/test/
evilsoup
fonte
2

Suponha que você esteja usando o gnu find , você pode usar a opção -delete:

find . -name test -delete

o que é mais fácil de lembrar.

Chun Yang
fonte
2

Como outra resposta aponta, você pode tentar encontrar todos os diretórios com o nome teste excluí-los

find -name "test" -type d -delete

Eu tive alguns problemas com compatibilidade cruzada no Mac, então usei este comando equivalente:

find -path "*/test" -type d -delete
  • -caminho : procura um padrão no nome do arquivo completo.

Em qualquer um dos casos, no entanto, se algum dos diretórios nomeados testtiver arquivos, eles findreclamarão Directory is not emptye não conseguirão remover o diretório.

Se você pretendia excluir todos os arquivos, incluindo o testdiretório, podemos usar o mesmo truque para excluir todos os arquivos dentro dos diretórios nomeados testprimeiro.

find -path "*/test/*" -delete

O padrão "*/test/*":, garantirá que apenas excluamos arquivos dentro de um diretório chamado /test/. Depois que os diretórios estiverem vazios, podemos prosseguir e excluir os diretórios usando o primeiro comando:

find -path "*/test" -type d -delete

Exemplo:

$ tree
.
├── mytest
│   └── test
│       └── blah.txt
├── test
│   ├── bar.jpg
│   └── dir
│       └── bar.bak
└── testdir
    └── baz.c

5 directories, 4 files

$ find -path "*/test" -type d -delete
$ tree
.
├── mytest
│   └── test
├── test
└── testdir
    └── baz.c

4 directories, 1 file

$ find -name "test" -type d -delete
$ tree
.
├── mytest
└── testdir
    └── baz.c

2 directories, 1 file
Karl
fonte