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
find
inicia un comando de búsqueda.-
./myfolder
le dice a find que comience con el directorio./myfolder
y su contenido. -
-mindepth 1
no coincidir con./myfolder
en 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. -
-delete
le 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