Identificar nombres de subdirectorios comunes entre dos directorios diferentes y eliminarlos

Identificar nombres de subdirectorios comunes entre dos directorios diferentes y eliminarlos

Tengo dos directorios dir1y dir2tienen cientos de subdirectorios en depth 1. Solo necesito información de los nombres de los subdirectorios que son comunes entre dir1y dir2y 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 -rfsimplemente ignora los que no existen.

Entonces es suficiente confind tododirectorios dir1y eliminarlos de dir2:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --

Algunas explicaciones. De forma predeterminada, findse imprimirán todos los directorios con la ruta completa, que es dir1. Entonces estamos usando -printfpara 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 xargla opción -0, lo que hace que todo esto sea seguro con respecto a los nombres de archivos con espacios. Luego xargsleerá la entrada estándar y ejecutará el rmcomando agregando todas las cadenas como argumentos.

Tenga en cuenta que antes de eliminarlos puede probar su línea de comando agregando echopara imprimir solo los rmcomandos:

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 lsen 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.

<( ... )

sustitución de procesos.

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 dir2pero no en dir1.

... | ( cd dir2 && xargs rm -rf )

cambie el directorio de trabajo para dir2luego ejecutar rm -rfcon la salida del comando anterior como argumentos. en efecto, esto eliminará los directorios que están dir2pero no en dir1.

Pruebe primero quitando la tubería xargse 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.

información relacionada