Remova todos os diretórios de dentro de um diretório pai, exceto um e seus descendentes

8

Eu quero remover o diretório B e D. Mas eu quero manter C e todos os seus arquivos e diretórios descendentes. Qual é o comando para remover todos os diretórios filhos de um diretório pai, exceto um diretório e seus filhos.

Ajuda apreciada.

    
por Joe Saad 29.07.2016 / 23:33

4 respostas

6

O que você quer é este comando:

find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;

Demo:

# List what's inside directory we want to remove
$ ls
file1  file2  keepMe/  removeA/  removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)               
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1  file2  keepMe/

Explicação:

  • find DIRECTORY chamar comando de localização para operar em DIRETÓRIO
  • -mindepth 1 : trabalhe apenas com o conteúdo do diretório, evite o próprio diretório que é o nível 0
  • -maxdepth 1 : impede a descida em subdiretórios ( rm -rf é recursivo de qualquer forma, portanto, não precisamos descer em subdiretórios para removê-los)
  • -type d : pesquisa apenas por diretórios
  • -not \( -name "keepMe" \) ignora o item com o nome que você deseja manter
  • -exec rm -rf {} \; executa a remoção em cada item encontrado
por Sergiy Kolodyazhnyy 29.07.2016 / 23:40
8

Usando os recursos extended glob do bash shell (que são habilitados por padrão nas instalações atuais do Ubuntu), dado

$ tree A
A
├── B
├── C
│   ├── ac1
│   └── ac2
└── D

5 directories, 0 files

você pode endereçar tudo excluindo C e seu conteúdo usando a expressão glob A/!(C) , ou seja,

$ echo A/!(C)
A/B A/D

Então, para remover tudo, exceto o diretório C e seu conteúdo, você pode simplesmente usar

rm -rf A/!(C)

saindo

$ tree A
A
└── C
    ├── ac1
    └── ac2

3 directories, 0 files
    
por steeldriver 30.07.2016 / 00:58
5

Um jeito fácil seria usar trash-cli

você pode instalá-lo com sudo apt-get install trash-cli

uma vez instalado, você pode navegar para o diretório pai A com cd /A e, em seguida, emitir o comando trash B D , onde B e D são os diretórios que você deseja remover (eles vão acabar na lixeira da unidade em que estão, portanto, se você cometer um erro, poderá recuperar os arquivos)

Testado no Ubuntu 16.04 e 14.04

    
por Elder Geek 29.07.2016 / 23:45
4

Basta usar o for loop de Bash e test para filtrar os diretórios desejados e o comando rm -rf para excluir diretórios de forma recursiva, assim:

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

Isso itera sobre todos os elementos (arquivos e diretórios) dentro de /path/to/parent/ e exclui o elemento recursivamente se o nome não for igual a dir_survive . Se o diretório pai for o diretório atual, você poderá escrever apenas * como caminho.

Se você não tiver certeza e quiser testar quais elementos seriam excluídos primeiro sem executar nenhuma ação, simplesmente substitua o rm -rf no comando acima por echo e ele só exibirá os candidatos de exclusão.

Veja um exemplo de execução:

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files
    
por Byte Commander 30.07.2016 / 00:09