Limpa recursivamente todas as pastas e subpastas de uma pasta que não contém arquivos [duplicados]

3

Eu tenho uma pasta com uma carga de pastas em pastas em pastas, etc ... Algumas das pastas têm arquivos, e outros não. Eu quero limpar a pasta principal, encontrando todos os diretórios sem arquivos e excluí-los. Um exemplo pode fazer mais sentido:

Então, se eu começar com isso:

  • %código%
    • %código%
      • mainFolder (vazio)
      • %código%
        • folder1
      • folder1 (vazio)
    • %código%
      • folder2 (vazio)
      • file.txt (vazio)
      • %código%
        • %código%
          • folder3 (vazio)
    • %código%
      • %código%
        • folder2

Eu devo acabar com isso:

  • %código%
    • %código%
      • %código%
        • folder1
    • %código%
      • %código%
        • folder2

Então:

  • folder3 foi excluído porque não tinha arquivos
  • folder1 foi excluído porque não tinha arquivos
  • folder1 foi excluído porque não tinha arquivos, mesmo todas as subpastas estavam vazias

Espero que isso faça sentido ...

A única idéia que tive foi começar em folder3 e percorrer recursivamente cada subpasta excluindo as que estão vazias.

    
por IMTheNachoMan 08.10.2017 / 05:52

3 respostas

10

Veja se isso faz o que você quer:

find mainFolder -depth -empty -type d -exec rmdir {} \;

Isso deve localizar diretórios em mainFolder usando uma travessia em profundidade que esteja vazia e remover esses diretórios. Como ele faz uma travessia em profundidade, ao remover subdiretórios, se o diretório pai ficar vazio, find irá identificá-lo como vazio e removê-lo também.

    
por 08.10.2017 / 06:27
1

Solução

Provavelmente existe alguma combinação de switches para find , mas acho que a abordagem Python é mais fácil (e é multi-plataforma, não que você precise disso):

import os

top = './mainFolder'
for root, dirs, files in os.walk(top, topdown=False):
    for name in dirs:
        dir_path = os.path.join(root, name)
        if not os.listdir(dir_path):  # An empty list is False
            os.rmdir(os.path.join(root, name))

Configuração e testes

Crie o diretório de arquivos

# https://stackoverflow.com/a/246128/295807
readonly script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd "$script_dir"

rm -rf mainFolder

mkdir -p mainFolder/{folder1/{folder1,folder2,folder3},folder2/{folder1,folder2,folder3/folder1/folder1},folder3/folder1}

touch mainFolder/folder1/folder2/file.txt
touch mainFolder/folder3/folder1/file.txt

Teste:

$ tree mainFolder/
mainFolder/
├── folder1
│   ├── folder1
│   ├── folder2
│   │   └── file.txt
│   └── folder3
├── folder2
│   ├── folder1
│   ├── folder2
│   └── folder3
│       └── folder1
│           └── folder1
└── folder3
    └── folder1
        └── file.txt

12 directories, 2 files

Execute o script Python:

python work.py

Teste:

$ tree mainFolder/
mainFolder/
├── folder1
│   └── folder2
│       └── file.txt
└── folder3
    └── folder1
        └── file.txt

4 directories, 2 files

Nota: se um arquivo for adicionado à pasta depois que o Python verificar se está vazio, mas antes de realmente apagá-lo, o Python levantará uma exceção! Na prática, isso não é um grande problema, porque o tempo entre essas duas etapas é medido em microssegundos, mas é algo para se estar ciente.

    
por 08.10.2017 / 06:26
1

Usando uma implementação de find que suporta -delete e -empty :

find mainFolder -type d -empty -delete

Isso fará uma travessia em profundidade da estrutura de diretórios com raiz em mainFolder e excluirá todos os diretórios vazios lá.

Usando o padrão find :

find mainFolder -depth -type d -exec sh -c 'rmdir "$1" 2>/dev/null' sh {} ';'

Isso tentará usar o diretório rmdir em todos os em mainFolder enquanto percorre a estrutura de maneira primordial. Como rmdir não pode excluir diretórios não vazios, somente os vazios serão excluídos. Erros do rmdir são descartados.

Para testar explicitamente cada diretório antes de executar rmdir sobre ele:

find mainFolder -depth -type d -exec sh -c 'd="$1"; set -- "$d"/*; [ ! -e "$1" ] && rmdir "$d"' sh {} ';'

Isso pressupõe que não haja arquivos ocultos nos diretórios.

    
por 08.10.2017 / 11:14