Remove árvores de diretórios vazios (removendo o máximo de diretórios possíveis, mas nenhum arquivo)

10

Suponha que eu tenha uma árvore dir assim:

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

Eu estou procurando um comando tal que quando eu insiro:

$ [unknown command] ROOTDIR

A árvore inteira do diretório pode ser excluída se não houver arquivo, mas somente dirs dentro da árvore inteira . No entanto, diga se existe um arquivo chamado hello.pdf em SUBDIR1:

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

Em seguida, o comando só deve excluir SUBDIR2 e abaixo.

    
por gsklee 07.11.2011 / 21:53

6 respostas

8

Alexis está perto. O que você precisa fazer é isto:

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

Isso primeiro detalha a árvore de diretórios até encontrar o primeiro diretório vazio e, em seguida, excluí-lo. Assim, fazendo o diretório pai vazio, que será então excluído, etc Isso irá produzir o efeito desejado (eu faço isso, provavelmente, 10 vezes por semana, então eu tenho certeza que é certo). : -)

    
por 08.11.2011 / 06:26
19
find ROOTDIR -type d -empty -delete

mesmo que

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

mas usa a ação "-delete" incorporada.

Note que "-delete" implica "-depth".

    
por 11.08.2012 / 21:18
3

Eu tentaria isso:

find ROOTDIR -type d -depth -exec rmdir {} \;
    
por 07.11.2011 / 22:11
1
rmdir $(find ROOTDIR -type d | sort -r)
    
por 07.11.2011 / 21:56
0

Eu faria isso:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
    
por 08.11.2011 / 04:15
0

Aqui estão alguns requisitos para que possamos fazer isso com segurança:

  1. remover subdiretórios primeiro e depois diretórios de nível superior, ou seja, precisamos classificar a listagem de diretórios ou usar rmdir --parents flag
  2. inicie ROOTDIR sempre com / ou ./ para evitar surpresas com arquivos que começam com -
  3. use a lista de diretórios terminados pelo NUL para trabalhar com nomes de diretórios com espaços

Aqui está como eu faria isso no shell:

find ./ROOTDIR -type d | sort -r | tr '\n' '
find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents
0' | xargs -0 rmdir --ignore-fail-on-non-empty

Se você não se importa com alguns erros redundantes, então você pode forçar a remoção de todos os diretórios com os pais e você não precisa fazer nenhuma classificação (você não pode classificar strings terminadas em NUL, o que adiciona tr)

find ./ROOTDIR -type d | sort -r | tr '\n' '
find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents
0' | xargs -0 rmdir --ignore-fail-on-non-empty
    
por 08.11.2011 / 13:04