Esto es probablemente 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 director de tal manera de obtener file1 y file2 en dir1 no dir2.
Respuestas:
Puedes hacer esto con GNU
find
y GNUmv
:Básicamente, la forma en que funciona si
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 unamv
para moverlo al directorio que desee (-exec mv … +
). El-t
argumento para lemv
permite especificar primero el directorio de destino, que es necesario porque la+
forma de-exec
coloca todas las ubicaciones de origen al final del comando. El-i
hacemv
preguntar antes de sobrescribir cualquier duplicado; puede sustituir-f
sobrescribirlos sin preguntar (o-n
no preguntar o 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:fuente
-exec +
modo que no ejecute una gran cantidad de procesos demv
mv
necesita el destino como argumento final, pero + tendría las fuentes como argumento final. Find incluso no acepta la sintaxis a la que la cambiaste (find: missing argument to `-exec'
)mv
tiene un-t
que podemos usar, así que lo cambiaré por eso.find
imprime archivos ocultos (punto) de forma predeterminada. La profundidad es relativa al directorio que pasa para buscar.find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'
si seEn zsh:
**/
recorre subdirectorios de forma recursiva. El calificador global solo.
coincide con los archivos normales yD
garantiza que se incluyan los archivos de puntos (de forma predeterminada, los archivos cuyo nombre comienza con a.
se excluyen de las coincidencias con comodines). Para limpiar los directorios ahora vacíos después, ejecutermdir dir1/**/*(/Dod)
:/
restringe a los directorios yod
ordena primero la profundidad de las coincidencias para eliminarlasdir1/dir2/dir3
antesdir1/dir2
.Si la longitud total de los nombres de archivo es muy grande, puede encontrar una limitación en la longitud de la línea de comando. Zsh tiene incorporados para
mv
yrmdir
que no se ven afectados por esta limitación: ejecutarzmodload zsh/files
para habilitarlos.Con solo herramientas POSIX:
o (más rápido porque no tiene que ejecutar un proceso separado para cada archivo)
fuente
Intenta hacer esto:
o para cada archivo que coincida
file[0-9]*
en el subdirectorio:Ver http://mywiki.wooledge.org/glob
fuente
{}
en mi problema real.Escribí dos funciones que pueden usar juntas que hacen exactamente eso, pueden limitar el nivel del directorio agregando un
-maxdepth $VAL
parámetro.fuente
Ampliando la respuesta popular a esta pregunta, ya que tenía un caso de uso para aplanar un directorio que contiene archivos del mismo nombre.
En este caso, la opción
-i
(--interactive
) pasada amv
no produciría el resultado deseado para aplanar la estructura del directorio y manejar los conflictos de nombres. Por lo tanto, simplemente se reemplaza con--backup=t
(equivalente a--backup=numbered
). Más documentación sobre la opción-b
(--backup
) disponible en https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options .Resultando en:
Cuyos rendimientos:
fuente
tar y zip tienen la capacidad de incorporar y luego eliminar una estructura de directorio, por lo que pude aplanar rápidamente un directorio anidado con
tar -cvf all.tar *
seguido de mover all.tar a una nueva ubicación y luego
tar -xvf all.tar --strip=4
fuente