Pregunta:
Probablemente esto sea muy simple, pero no puedo entenderlo. Tengo una estructura de directorio como esta ( dir2
está dentro de dir1
):
/dir1
/dir2
|
--- file1
|
--- file2
¿Cuál es la mejor manera de 'aplanar' esta estructura de directorios de tal manera como para obtener file1
y file2
en dir1
no dir2
?
Respuesta:
Puede hacer esto con GNU find
y GNU mv
:
find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +
Básicamente, la forma en que funciona si esa find
pasa por todo el árbol de directorios y para cada archivo ( -type f
) que no está en el directorio de nivel superior ( -mindepth 2
), ejecuta un mv
para moverlo al directorio que quiero ( -exec mv … +
). El argumento -t
de mv
permite especificar primero el directorio de destino, lo cual es necesario porque la forma +
de -exec
coloca todas las ubicaciones de origen al final del comando. El -i
hace que mv
pregunte antes de sobrescribir cualquier duplicado; puede sustituir -f
para sobrescribirlos sin preguntar (o -n
para no preguntar ni sobrescribir).
Como señala Stephane Chazelas, lo anterior solo funciona con herramientas GNU (que son estándar en Linux, pero no en la mayoría de los otros sistemas). Lo siguiente es algo más lento (porque invoca mv
varias veces) pero mucho más universal:
find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'
POSIXly, pasando más de un argumento, pero usando sh
para reordenar la lista de argumentos para mv
para que el directorio de destino sea el último:
LC_ALL=C find /dir1 -path '/dir1/*/*' -type f -exec sh -c '
exec mv "$@" /dir1' sh {} +