Tengo un directorio de muchos archivos, algo así como 50,000 pdf y otros archivos en un servidor. Necesito mover los específicos a otro directorio. Puedo generar una lista de los archivos que deben moverse en csv o en cualquier otro formato de texto.
Lo que necesito hacer es ejecutar un script bash y mover o copiar los archivos que figuran en el archivo de texto a otro directorio.
¿Hay una manera fácil de hacer esto? Cualquier sugerencia o recursos serán muy apreciados.

Respuestas:
rsync tiene varias opciones que pueden tomar una lista de archivos con el proceso (
--files-from,--include-from, etc.).Por ejemplo, esto hará el truco:
fuente
rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directoryPara evitar un uso inútil de
cat(y si no lo usarsync):Esto manejará cualquier nombre de archivo válido, a menos que contenga una nueva línea, si los archivos se enumeran uno por línea.
fuente
mvlos colapsará en el mismo directorio de destino. Elrsyncenfoque en la respuesta aceptada no sufre esta limitación.suponiendo bash, además de
listoffilescontener un archivo por línea. Mi única objeción a la ruta rsync es que el OP solicita un método para mover los archivos, no copiarlos. rsync tiene más banderas que una boda real, así que estoy seguro de que puede modificarse aún más para hacerlo, ¡pero a veces más simple es mejor!fuente
while read -r file; do mv "$file" /path/of/destination ; done < listoffilesEsto depende del formato del archivo de texto que tenga. Por ejemplo, si tiene la lista de archivos escritos de manera que cada archivo se encuentre en una nueva línea. Puedes usar xargs como:
Además, puede usar el
findcomando con la-execopción. para copiar / mover los archivos.fuente
Rsync tiene el beneficio adicional sobre los comandos
cpomvporque creará automáticamente carpetas si no existen.fuente
/path/to/sourcenecesario cuando toma las rutas de la lista de archivos?Creo que la respuesta rsync es mejor, pero solo para otra opción:
fuente
Copié accidentalmente el contenido completo de un directorio en un directorio de destino en lugar de mover el directorio completo. Esto dio como resultado un directorio de destino desordenado en lugar de agregar el directorio de origen al directorio.
Para solucionar esto, hice lo siguiente:
ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomoveEl comando anterior crea el archivo filetomove que será una lista de todos los contenidos del directorio de destino, ordenados por tiempo inverso, lo que significa más antiguo a más nuevo.Luego creé un subdirectorio del directorio de destino ahora desordenado para mover las cosas.
mkdir /path/to/cluttered/destination/directory/newsubdirectoryLuego repetí el listado del directorio, excepto el listado en la pantalla y mostrando más detalles.
ls -lrht /path/to/cluttered/destination/directory/Esta línea enumera el directorio, ordenado por fecha ascendente (orden inverso por hora) y muestra más información, incluida la marca de fecha / hora de cada archivo en el directorio de destino ahora desordenado. Me refiero a esto, comenzando en la parte superior para mostrar qué directorios y archivos quiero mantener donde estaban. Habrá un vacío en la marca de fecha / hora de los archivos donde comienzan todos los archivos nuevos que no deberían estar allí.Luego edité el archivo filetomove creado en el primer paso anterior (que está ordenado por fecha) y eliminé los pocos de la lista que estaban allí anteriormente y que quiero quedar del directorio original.
vim /opt/dircheck/filestomoveElimine desde la parte superior todos los archivos que no desea mover.Luego utilicé el comando enumerado anteriormente en esta publicación para mover los archivos de mi lista al nuevo directorio que hice.
sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectoryEsto movió todos los archivos en una fracción de segundo. (Nota: es posible que no necesite el sudo al principio, esto es una cuestión de permisos de archivo).
Ahora mi directorio de destino original es agradable y limpio y contiene un nuevo directorio con todos los archivos y directorios que lo estaban abarrotando.
fuente
Si (y solo si), no tiene caracteres desagradables en los nombres de archivo (espacios, líneas nuevas, lo que confundiría a xargs sobre cómo dividir las cosas en argumentos individuales), y genera una lista de archivos separados por líneas nuevas (un archivo por línea), podrías hacer algo como.
(En general, mira man xargs , es increíble)
Si su MV particular no tiene la opción -t, también podría hacer algunos trucos como
Nota: ninguno de estos funcionará como se espera si hay nombres de archivo con nuevas líneas en ellos.
fuente
cp,mvy similares no tienen-topción en bsd , y el segundo ejemplo con subshell no funcionó para mí (/path/to/movese adjunta como el último nombre de archivo)(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mvIntenta algo como:
fuente
while read line; do mv $line /images; done < list.txtcomo un solo comandoLo siguiente funcionó para mí donde necesitaba copiar todos los archivos PNG desde una ruta específica (y todos los subdirectorios) a una nueva ubicación, preservando la estructura del directorio:
Debido a que RSYNC crea primero el espejo de la estructura de directorios, luego sincroniza los archivos, puede terminar con un exceso de carpetas que están vacías. Usé el indicador --prune-empty-dirs para eliminar estos directorios vacíos.
No tengo afiliación, pero pensé que era correcto dar crédito a la fuente que inspiró esta solución: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/
fuente