Como faço para excluir todos os diretórios vazios em um diretório da linha de comando?

58

Digamos que eu tenha um diretório chamado foo/. Esta pasta inclui subdiretórios. Como posso excluir todos os diretórios vazios em um comando?

justingrif
fonte

Respostas:

119

Tente este comando:

find . -empty -type d -delete

O findcomando é usado para procurar arquivos / diretórios que correspondam a um critério de pesquisa específico a partir do caminho especificado, neste caso, o diretório atual (daí o .).

A -emptyopção é verdadeira para qualquer arquivo e diretório que esteja vazio.

A -type dopção é verdadeira para o tipo de arquivo especificado; nesse caso, dsignifica o diretório do tipo de arquivo .

A -deleteopção é a ação a ser executada e é verdadeira para todos os arquivos encontrados na pesquisa.

Conta
fonte
Eu acho que essa é a maneira mais fácil de fazer isso, então vou adiante e marcar isso como respondido.
justingrif
Ei, Bill, tentei postar outra pergunta semelhante e ela não me deixou, porque dizia que era uma estupidez, então eu esperava que você pudesse me responder aqui. Digamos que eu queira fazer a mesma coisa que acima, mas remova todos os diretórios, estejam eles vazios ou não.
justingrif
3
A maneira como você iria remover diretórios, independentemente se eles são ou não vazia, digite o seguinte comando: rm -rf <directory-name>. Isso removerá o diretório, juntamente com todo o seu conteúdo, incluindo arquivos e subdiretórios. A -ropção significa excluir recursivamente, enquanto o -fcomando significa não avisar antes de excluir. Se você deseja ser solicitado antes de excluir um diretório / arquivo, substitua a -fopção pela -iopção
Bill
E se houvesse alguns arquivos no referido diretório que eu queria manter. Então, eu queria excluir todos os diretórios em / foo / bar /, mas manter todos os arquivos que possam estar lá.
justingrif
2
É possível fazer isso usando um canal para alimentar o stdoutcomando de um (por exemplo find) no stdinoutro (por exemplo rm), no entanto, tenha muito cuidado, pois pode apagar ou excluir arquivos / diretórios que você não deseja excluir! Para mais informações sobre como fazer isso, consulte as manpáginas de cada um desses comandos. Para estar seguro, sempre teste essas coisas em um diretório temporário antes de experimentar a coisa real.
Bill
11

Você pode aproveitar a rmdirrecusa do comando em excluir diretórios não vazios e a find -depthopção de percorrer a árvore de diretórios de baixo para cima:

find . -depth -exec rmdir {} \;  

(e ignore os erros) ou acrescente-os 2>/dev/nullpara realmente ignorá-los.

A -depthopção para findcomeçar a localizar na parte inferior da árvore de diretórios.

rm -rfexcluirá todos os arquivos no diretório (e seus subdiretórios e ....) E todos os diretórios e tudo mais.

waltinator
fonte
8
rmdir *

Excluirá todos os diretórios vazios. Irá gerar um erro para cada diretório e arquivo não vazio, para impedir que esses erros atrapalhem seu terminal, use

rmdir * 2> /dev/null
evilsoup
fonte
Isso não é adequado para scripts, pois ele sai com um código de status diferente de zero, mas funciona.
the_drow
@the_drow como isso se torna inadequado? A propósito, você também pode usar rmdir * 2>/dev/null || true. (O find (1) é o melhor caminho para criação de scripts, mas por outro motivo: porque expressa melhor o que você quer fazer.)
Alois Mahdal
Costumo fazer isso em $HOME. Com um sorriso maligno.
Alois Mahdal
Porque relatará falha se alguns dos diretórios não estiverem vazios.
217156 Declara
isso é mais rápido que o método find? Alguém comparou os dois?
Xerus
1
find . -type d -empty -delete -maxdepth 1

Pois se você deseja excluir apenas os subdiretórios diretos de foo/.

Simon Baars
fonte
0

Abordagem Python

$ tree                                                                                                                                                                                  
.
├── empty_dir1
├── empty_dir2
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

4 directories, 4 files
$ python -c 'import os;empty=[r for r,s,f in os.walk(".") if not f and not s and r != "." ];map(lambda x: os.rmdir(x),empty)'
$ tree
.
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

Isso funciona assim:

  • usamos a os.walk()função para percorrer recursivamente a árvore de diretórios. Em cada iteração restá definido para a pasta atual que está acessando, scontém lista de diretórios dentro r, e fconterá lista de arquivos nessa pasta. É claro que se fe sestamos vazios, sabemos que restá vazio.
  • A primeira compreensão de lista nos permite criar empty, a lista de todos os diretórios vazios, com base na avaliação mencionada acima.
  • segunda função, map()é usada para executar os.rmdir()em cada item da emptylista. A compreensão da lista pode ser usada e também alternativa.

Como um script, seria assim:

#!/usr/bin/env python
import os
empty=[]
for r,s,f in os.walk("."):
    if not f and not s and r != ".":
        empty.append(r)

for i in empty:
    os.rmdir(i)
Sergiy Kolodyazhnyy
fonte
muito complicado para perguntas simples :(
nurulhudamustaqim
@nurulhudamustaqim Depende do ponto de vista. Para muitos usuários de Linux que estão acostumados a Python, isso é realmente muito modesto :) E além da variedade. A administração moderna do sistema não se limita ao bash ou /bin/shapenas e o Python é realmente uma linguagem mais elegante do que os dois.
Sergiy Kolodyazhnyy 17/02