Esto eliminará todas las carpetas dentro de ./myfolder excepto que ./myfolder/test2 y todo su contenido será preservado:
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Cómo funciona
findinicia un comando de búsqueda.-
./myfolderle dice a find que comience con el directorio./myfoldery su contenido. -
-mindepth 1no coincidir con./myfolderen sí mismo, solo los archivos y directorios debajo de él. -
! -regex '^./myfolder/test2\(/.*\)?'le dice a find que excluya (!) cualquier archivo o directorio que coincida con la expresión regular^./myfolder/test2\(/.*\)?.^coincide con el inicio del nombre de la ruta. La expresión(/.*\)?coincide con (a) una barra inclinada seguida de cualquier cosa o (b) nada en absoluto. -
-deletele dice a find que elimine los archivos coincidentes (es decir, no excluidos).
Ejemplo
Considere una estructura de directorios que se parece 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
Podemos ejecutar el comando de búsqueda (sin -delete ) para ver con qué coincide:
$ 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
Podemos verificar que esto funcionó mirando los archivos que quedan:
$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Usando bash:
shopt -s extglob
rm -r myfolder/!(test2)/
Ejemplo:
$ 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 '{}' \;
Elimine echo si está satisfecho con la lista de archivos.
Usando -mindepth 1 se asegurará de que la superior el directorio no está seleccionado.
$ 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
Pero un -not -name test2 no evitar subdirectorios dentro de 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
Para hacer eso, necesitas algo como podar:
$ 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
Pero no use delete , ya que implica depth y eso comenzará a borrarse desde la ruta más larga:
$ 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 (quitar el echo si realmente desea borrar):
$ 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
O, también usa maxdepth si todo lo que necesita es eliminar directorios (y todo lo que hay dentro) (elimine el echo para borrar):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
Un -delete seguirá fallando si el directorio no está vacío:
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty