¿Cómo mover recursivamente todos los archivos (incluidos los ocultos) de una subcarpeta a una carpeta principal en * nix?

14

Esta es una pregunta un poco vergonzosa, pero tengo que admitir que al final de mi carrera todavía tengo preguntas sobre el comando mv.

Con frecuencia tengo este problema: necesito mover todos los archivos recursivamente un nivel hacia arriba. Digamos que tengo una carpeta foo y una barra de carpetas dentro de ella. Bar tiene un montón de archivos y carpetas, incluidos archivos y carpetas de puntos. ¿Cómo muevo todo en la barra al nivel foo?

Si foo está vacío, simplemente muevo la barra un nivel más arriba, elimino foo y cambio el nombre de la barra a foo. Parte del problema es que no puedo entender cuál es el comodín de mv para "todo, incluidos los puntos". Una parte de esta pregunta es esta: ¿hay una discusión en profundidad de los comodines que los comandos cp y mv usan en alguna parte (buscar en Google esto solo trae tutoriales muy básicos).

programador muerto
fuente

Respuestas:

19

En Bash (y algunos otros), puede usar la expansión de llaves para lograr esto en una línea:

mv bar/{,.}* .

La coma separa un punto nulo y un punto, por lo que el mvcomando ve los nombres de archivo que coinciden *y.*

Pausado hasta nuevo aviso.
fuente
esto intenta mover '...' también, falla con el mensaje 'recurso está ocupado'. Funciona no obstante.
Xananax
3
Sugerido por un usuario anónimo:To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* .
HopelessN00b
2

La forma más fácil de hacer esto es hacerlo en dos comandos, porque * no coincide con lo que sea.

cd /foo
mv bar/* ./
mv bar/.??* ./

No desea utilizar la barra /.* que descubrí al cometer este error:

rm -rf ./.* 

Esto es algo malo. Alguien quiere adivinar por qué? ;-)

Matt Simmons
fuente
No creo que Bash o Zsh se expandan .*a .y ... Zsh no lo hace para mí al menos.
Mikael S
Mikael: Puedo prometer que bash lo hace (o al menos lo hizo), ya que tuve que recuperar los directorios de usuarios que eliminé al hacer eso
Matt Simmons
2

Lo primero que debe saber sobre el globbing: lo hace el shell, no el comando. Consulte la página de manual de su shell para ver todos los detalles.

Jeff Leyser
fuente
2

Éste recoge todos los archivos de las subcarpetas y los mueve al directorio actual

find . -type f -exec mv -iv \{} . \;

Si desea sobrescribir archivos con el mismo nombre, use

yes y | find . -type f -exec mv -iv \{} . \;
michelek
fuente
1

mv .??* *se encargará de todo, excepto el punto seguido de un solo carácter. Si eso es común para su situación, puede agregar .[a-zA-Z0-9]*. Que aún dejará archivos con nombres como .;, .^, y .^I(TAB). Si necesita manejar todo, deberá ser un poco más complejo.

mv .. `ls -f | egrep -v '^.$|^..$'
mpez0
fuente
0

Si tiene una estructura de directorio /foo/bar/y desea mover todos los archivos en barun paso anterior, vaya al bardirectorio y escriba lo siguiente:

find . -depth -print0 | cpio --null -pvd ../

En general, creo que cpio(1)es mejor para este tipo de tareas. Puede consultar la documentación detallada emitiéndola info cpioen su shell.

fim
fuente