Tengo un montón de archivos .zip en varios directorios:
Fol1/Fol2
Fol3
Fol4/Fol5
¿Cómo los movería a una carpeta base común?
Tengo un montón de archivos .zip en varios directorios:
Fol1/Fol2
Fol3
Fol4/Fol5
¿Cómo los movería a una carpeta base común?
Respuestas:
Vaya al directorio de nivel superior del árbol que contiene los archivos zip ( cd …
), luego ejecute
mv **/*.zip /path/to/single/target/directory
Esto funciona fuera de la caja en zsh. Si su shell es bash, shopt -s globstar
primero deberá ejecutarlo (puede y debe poner este comando en su ~/.bashrc
). Si su shell es ksh, set -o globstar
primero deberá ejecutarlo (ponerlo en su ~/.kshrc
).
Alternativamente, use find
, que funciona en todas partes sin una preparación especial, pero es más complicado:
find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;
Si desea eliminar directorios vacíos después, en zsh:
rmdir **/*(/^Fod)
En bash o ksh:
rmdir **/*/
y repita siempre que haya directorios vacíos para eliminar. Alternativamente, en cualquier caparazón
find . -depth -type d -empty -exec rmdir {} \;
find
comando anterior funcionó en bash, pero tuvo que cambiar a find . -name
etc. para que funcione.
.
está implícito para GNU find pero no para otros, lo he agregado explícitamente.
Si usa bash versión 4 o superior o zsh , también puede usar globbing recursivo:
mv **/*.zip /path/to/move/zip/files/to
Esto moverá SOLAMENTE los archivos y no sus rutas relativas, por lo que pueden ocurrir colisiones.
Este es seguro al mover datos y sin errores, lo que es compatible con la mayoría de las distribuciones independientemente de las versiones. Este comando escaneará subdirectorios y luego se moverá o copiará a su nuevo directorio de destino.
find . -name *.flac -exec mv '{}' "./flac/" ";"
*.flac
a algo como *.zip
en su caso. O *.doc
simplemente cualquier extensión funciona.mv
es el comando para mover archivos, o puede usar cp
para copiar datos en lugar de moverlos../flac/
es el directorio de destino al que quiero mover todos los archivos FLAC. También puedes darle un camino completo como/home/myid/flac/
Ejemplo completo. (en este caso, hay muchos subdirectorios con el nombre del artista de música en /home/myid/Music/
y luego los archivos FLAC están en diferentes niveles de subdirectorios. Dado que no necesito carpetas de artistas pero quiero tener todos los archivos FLAC en un directorio en/home/myid/Music/flac/
cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls
Luego mostrará todos los archivos FLAC.
;
hacer?
Como un hack bash, podrías usar el poder de tar
:
(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/
Esto tiene la ventaja de que no depende de las extensiones de archivo, ya que utiliza el file
comando para elegir los archivos a mover y conserva la estructura del directorio, pero no funciona con rutas que contienen espacios.
La final rm
está ahí solo para eliminar los archivos originales (porque @InquilineKea dice que no le importa la carpeta original en el comentario).
Por supuesto, esto es particularmente adecuado si las carpetas de origen / destino / están en discos diferentes. De lo contrario, las otras soluciones propuestas son más eficientes (incluso si se basan en convenciones de nomenclatura, en lugar del file
contenido).
Suponiendo que tiene las versiones GNU de find y mv, lo siguiente será más eficiente que las respuestas basadas en find existentes:
find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +
Usar un +
al final de find -exec significa que se pasará una lista de archivos al comando mv, en lugar de ejecutar un comando mv por archivo encontrado. Sin embargo, una limitación de esto es que solo puede colocar el '{}' al final del comando, lo que requiere el uso de la opción mv --target-directory, y que yo sepa, eso es un GNU-ismo.