Questo eliminerà tutte le cartelle all'interno di ./myfolder tranne che ./myfolder/test2 e tutto il suo contenuto sarà preservato:
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Come funziona
findavvia un comando find.-
./myfolderdice a find di iniziare con la directory./myfoldere il suo contenuto. -
-mindepth 1non corrisponda a./myfolderstesso, solo i file e le directory sotto di esso. -
! -regex '^./myfolder/test2\(/.*\)?'dice a find di escludere (!) qualsiasi file o directory corrispondente all'espressione regolare^./myfolder/test2\(/.*\)?.^corrisponde all'inizio del nome del percorso. L'espressione(/.*\)?corrisponde a (a) una barra seguita da qualsiasi cosa o (b) niente del tutto. -
-deletedice a find di cancellare i file corrispondenti (cioè non esclusi).
Esempio
Considera una struttura di directory simile a;
$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Possiamo eseguire il comando find (senza -delete ) per vedere cosa corrisponde:
$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
Possiamo verificare che abbia funzionato guardando i file che rimangono:
$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Usando bash:
shopt -s extglob
rm -r myfolder/!(test2)/
Esempio:
$ tree myfolder/
myfolder/
├── test1
│ └── file1
├── test2
│ └── file2
└── test3
└── file3
$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
└── file2
1 directory, 1 file
tl;dr
find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
-exec echo rm -rf '{}' \;
Rimuovi echo se sei soddisfatto dell'elenco di file.
Usando -mindepth 1 farà in modo che il top la directory non è selezionata.
$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Ma un -not -name test2 non evitare le sottocartelle all'interno di test2 :
$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Per farlo, hai bisogno di qualcosa come prune:
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Ma non utilizzare delete , poiché implica depth e questo inizierà a cancellare dal percorso più lungo:
$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test
Usa rm -rf (rimuovi il echo se vuoi effettivamente cancellare):
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3
Oppure, anche usa maxdepth se tutto ciò di cui hai bisogno è eliminare le directory (e tutto ciò che contiene) (rimuovi il echo cancellare effettivamente):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
Un -delete fallirà ancora se la directory non è vuota:
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty