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
find
avvia un comando find.-
./myfolder
dice a find di iniziare con la directory./myfolder
e il suo contenuto. -
-mindepth 1
non corrisponda a./myfolder
stesso, 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. -
-delete
dice 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