Tengo dos directorios dir1
y dir2
tienen cientos de subdirectorios en depth 1
. Solo necesito información de los nombres de los subdirectorios que son comunes entre dir1
y dir2
y los elimino sistemáticamente dir2
. No necesito comparar archivos o contenido de archivos. Ejecutando
diff -qr dir_one dir_two | sort
También produce los nombres de los archivos, que no me interesan en este momento.
Respuesta1
Para su caso de uso, puede evitaridentificarlos directorios comunes porque rm -rf
simplemente ignora los que no existen.
Entonces es suficiente confind
tododirectorios dir1
y eliminarlos de dir2
:
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --
Algunas explicaciones. De forma predeterminada, find
se imprimirán todos los directorios con la ruta completa, que es dir1
. Entonces estamos usando -printf
para imprimir solo el nombre del archivo sin los directorios principales (%f) más la otra ruta "dir2" donde queremos eliminar. Además, terminamos la cadena con el byte nulo '\0' en lugar de usar una nueva línea para usar xarg
la opción -0
, lo que hace que todo esto sea seguro con respecto a los nombres de archivos con espacios. Luego xargs
leerá la entrada estándar y ejecutará el rm
comando agregando todas las cadenas como argumentos.
Tenga en cuenta que antes de eliminarlos puede probar su línea de comando agregando echo
para imprimir solo los rm
comandos:
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --
solo paralistalos directorios comunes que podría usar ls
en lugar de rm
(agregando 2>/dev/null para ignorar los que no existen):
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null
Respuesta2
comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )
con saltos de línea para facilitar la lectura:
comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
<( cd dir2 && find -maxdepth 1 -type d | sort ) \
| ( cd dir2 && xargs rm -rf )
explicación
find -maxdepth 1 -type d
enumere solo directorios sin subdirectorios.
cd dir1 && find -maxdepth 1 -type d | sort
primero cambie al directorio y luego enumere los directorios.
<( ... )
comm -1 -3 <( ... ) <( ... )
tome la primera entrada y la segunda entrada e imprima líneas exclusivas para la segunda entrada. en efecto, esto imprimirá directorios que están dir2
pero no en dir1
.
... | ( cd dir2 && xargs rm -rf )
cambie el directorio de trabajo para dir2
luego ejecutar rm -rf
con la salida del comando anterior como argumentos. en efecto, esto eliminará los directorios que están dir2
pero no en dir1
.
Pruebe primero quitando la tubería xargs
e inspeccionando la salida.
Respuesta3
find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c | egrep -v '^ 1 ' | while read n de ; do echo rm -rfv dir2/$de ; done
elimine el eco cuando sea correcto.