¿Cómo puedo mover todos los archivos en subdirectorios de forma recursiva a un solo directorio?

10

Estoy tratando de recopilar todos los archivos en el directorio actual y todos los subdirectorios en un directorio. Estoy intentando algo como lo siguiente

find -type f -exec mv {} collection/{} \; 

el comando anterior no funcionará porque el segundo {}proporciona la ruta completa, ¿cómo puedo recopilar todos los archivos?

Conejo conejo
fuente

Respuestas:

14

Elimine el {}de mv, mvlo tomará como directorio de destino ignorando los directorios principales:

find -type f -exec mv {} collection/ \;
Lekensteyn
fuente
ohh eso no se me ocurrió. gracias :)
Bunny Rabbit
Como digo en mi respuesta a la pregunta, esta es potencialmente una mala idea. Quizás usar el argumento -maxdepth 1ayudaría.
loevborg
Ahora que lo pienso, parece que leí mal tu pregunta :) Lo siento.
loevborg
@loevborg: He agregado "recursivamente" al título ahora. Si aún hay confusión,
edítelo
1
Una variación más rápida de esta respuesta esfind -type f -print0|xargs -0r mv -it colection/
hildred
5

En lugar de usar find(lo que hace bien el trabajo), también podría usar el shell para este fin.

Digamos que desea todos los archivos de $ PWD a $ DEST. El intento natural sería:

mv $PWD/* $DEST

¿Como funciona esto? La expresión "$ PWD / *" se expande a los nombres de todos los archivos en ese directorio. Esta característica de shell se llama "globbing". El último argumento de mves el directorio de destino. Si tiene muchos archivos, esto no funcionará porque la longitud de la línea de comando es limitada.

Pero la solución tiene el problema de que omite archivos de puntos, o archivos, archivos y directorios "ocultos" cuyo nombre comienza con un ".". Para resolver esto, debe decirle a su shell que incluya archivos de puntos cuando haga glob. Para hacer esto, use

shopt -s dotglob

cuando se usa bash(y probablemente lo use a bashmenos que haya cambiado el valor predeterminado). En este shell, el comando anterior también funcionará para los archivos de puntos.

Como comentario adicional, en zsh, tiene la opción de elegir esto caso por caso. Para hacer esto, pon

setopt extendedglob

en su .zshrc. Entonces puedes usar

mv $PWD/*(D) $DEST

para mover todos los archivos, incluidos los archivos de puntos. (La "D" tiene el efecto de habilitar temporalmente la opción "GLOB_DOTS").

Ahora la pregunta original era mover todos los archivos normales (no directorios) de todos los subdirectorios y sus subdirectorios a un solo directorio. Esto se puede lograr con zsh:

mv $PWD/**/*(D.)

Aquí la expresión **/*hace que el globber descienda recursivamente en subdirectorios. Los Dmedios "también seleccionan archivos de puntos"; los .medios "solo seleccionan archivos regulares, no directorios".

loevborg
fuente
bueno, también quería volver a todos los subdirectorios, pero gracias de todos modos la información es útil, me encuentro con esta situación muchas veces :)
Bunny Rabbit
En realidad, find no es excesivo para esto, el globbing seleccionará todas las coincidencias, no solo los archivos, sino también los directorios. Si eres preocupaciones sobre el rendimiento, también se puede usar algo como: find -type f -exec mv -t collection/ {} +. Consulte la página del manual sobre cómo funciona esto.
Lekensteyn
Lekensteyn, tienes razón. Actualicé la respuesta ahora que he entendido la pregunta.
loevborg
2
Maravillosa respuesta, lástima que no sea particularmente relevante para la pregunta :).
crazy2be