El problema
Tengo una estructura de directorio, por ejemplo, algo como esto (aquí las barras inclinadas representan carpetas):
./A
./B/A/A
./B/A/B
./B/B/
./B/C
./C/
Y necesito eliminar recursivamente todo excepto algunos archivos y directorios:
./A
./B/A
Después de ejecutar el comando / script que estoy buscando, quiero que quede la siguiente jerarquía:
./A
./B/A/A
./B/A/B
El intento de solución
Traté de usar find
( -print
es un marcador de posición):
find \( -path ./A -or -path ./B/A \) -prune -or -print
Esto no funciona porque elimina los directorios principales de las entradas en la lista "no tocar":
$ find \( -path ./A -or -path ./B/A \) -prune -or -print
.
./B
./B/B
./B/C
./C
Especialmente, esto elimina ./B
mientras necesito mantener ./B/A
. Diablos, elimina el directorio actual, después de todo.
Quiero evitar las invocaciones recursivas (es decir find -exec something-that-calls-find.sh
), ya que las listas de directorios que manejaré son bastante grandes ...
fuente
./B
y, por lo tanto, lo eliminará a./B/A
pesar de que esté en la lista "ignorar".-exec rm -rf {} \; -prune
y eliminar.*
parte de la expresión regular, al menos en términos de rendimiento; 2) He encontrado una solución más fácil de escribir (sin ruta-> transformación de expresiones regulares); Lo publicaré en breve.Aquí está mi propia solución para eso.
NOTA: No soy un gran amante de la portabilidad cuando se trata de shell y utilidades, por lo que posiblemente depende en gran medida de Bash 4 y GNU find.
Código
Explicación
La
find
línea de comando resultante se construye como una cadena de-predicates -actions -or
secuencias.Esto significa lo siguiente: para cada ruta, si tiene
-predicates
éxito, haga-actions
, de lo contrario continúe con la siguiente secuencia. El último elemento de la cadena es justo-actions
, que es el caso predeterminado.Aquí, estoy haciendo
-prune
todos los parches encontrados directamente en$EXCEPTIONS
. Esto dejafind
de descender más allá de estos nombres.A continuación, no estoy haciendo nada por todos los padres de padres
$EXCEPTIONS
. No queremos eliminar los directorios principales de excepciones, ya que la eliminación es recursiva.Finalmente, estoy alimentando todos los parches restantes (el caso predeterminado) a
xargs rm -r
. Esto es más rápido que-exec rm -r {} \;
porque solo serm
generará uno .También lo hago
-prune
por ellos porque no tiene sentido eliminarlos explícitamente./A/B/C
si vamos a eliminarlos./A/B
.PD: esto terminó en mi biblioteca de fragmentos :)
fuente