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/directory
Para 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
mv
los colapsará en el mismo directorio de destino. Elrsync
enfoque en la respuesta aceptada no sufre esta limitación.suponiendo bash, además de
listoffiles
contener 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 < listoffiles
Esto 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
find
comando con la-exec
opción. para copiar / mover los archivos.fuente
Rsync tiene el beneficio adicional sobre los comandos
cp
omv
porque creará automáticamente carpetas si no existen.fuente
/path/to/source
necesario 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/filestomove
El 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/newsubdirectory
Luego 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/filestomove
Elimine 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/newsubdirectory
Esto 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
,mv
y similares no tienen-t
opción en bsd , y el segundo ejemplo con subshell no funcionó para mí (/path/to/move
se adjunta como el último nombre de archivo)(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mv
Intenta algo como:
fuente
while read line; do mv $line /images; done < list.txt
como 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