Rimuove tutte le directory da una directory padre tranne una e i suoi discendenti

8

Voglio rimuovere la directory B e D. Ma voglio mantenere C e tutti i suoi file e directory discendenti. Qual è il comando per rimuovere tutte le directory figlio di una directory padre tranne una directory e i suoi figli.

Aiuto apprezzato.

    
posta Joe Saad 29.07.2016 - 23:33

4 risposte

6

Quello che vuoi è questo 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/

Spiegazione:

  • find DIRECTORY comando call find per operare su DIRECTORY
  • -mindepth 1 : lavora solo con i contenuti della directory, evita la directory stessa che è di livello 0
  • -maxdepth 1 : impedisce di discendere in sottodirectory ( rm -rf è comunque ricorsiva, quindi non è necessario scendere nelle sottodirectory per rimuoverle)
  • -type d : cerca solo le directory
  • -not \( -name "keepMe" \) ignora l'elemento con il nome che vuoi mantenere
  • -exec rm -rf {} \; esegue la rimozione su ogni elemento trovato
risposta data Sergiy Kolodyazhnyy 29.07.2016 - 23:40
8

Uso delle funzioni est glob della shell bash (che sono abilitate di default nelle attuali installazioni di Ubuntu), date

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

5 directories, 0 files

puoi indirizzare tutto tranne il C e il suo contenuto usando l'espressione glob A/!(C) i.e.

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

Quindi per rimuovere tutto tranne la directory C e il suo contenuto puoi semplicemente usare

rm -rf A/!(C)

lasciando

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

3 directories, 0 files
    
risposta data steeldriver 30.07.2016 - 00:58
5

Un modo semplice sarebbe usare il cestino-cli

puoi installarlo con sudo apt-get install trash-cli

una volta installato, puoi accedere alla directory padre A con cd /A e quindi inviare il comando trash B D dove B e D sono le directory che vuoi rimuovere (finiranno nel cestino per l'unità in cui si trovano, quindi se fai un errore puoi recuperare i file)

Testato su Ubuntu 16.04 e 14.04

    
risposta data Elder Geek 29.07.2016 - 23:45
4

Utilizza semplicemente for loop di Bash e test per filtrare le directory desiderate e il comando rm -rf per eliminare in modo ricorsivo le directory, come questo:

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

Questo itera su tutti gli elementi (file e directory) all'interno di /path/to/parent/ ed elimina l'elemento in modo ricorsivo se il suo nome non è uguale a dir_survive . Se la directory genitore è la directory corrente, puoi solo scrivere * come percorso.

Se non sei sicuro e vuoi verificare quali elementi verrebbero eliminati per primi senza eseguire alcuna azione, sostituisci semplicemente rm -rf nel comando precedente con echo e verranno visualizzati solo i candidati eliminati.

Ecco un esempio di esecuzione:

$ 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
    
risposta data Byte Commander 30.07.2016 - 00:09

Leggi altre domande sui tag