web-dev-qa-db-fra.com

Fichiers spécifiques Linux (mv ou cp) à partir d'une liste de fichiers texte?

J'ai un répertoire de nombreux fichiers, quelque chose comme 50 000 pdf et autres fichiers sur un serveur. J'ai besoin de déplacer des fichiers spécifiques vers un autre répertoire. Je peux générer une liste des fichiers qui doivent être déplacés au format csv ou tout autre format de texte.

Ce que je dois faire, c'est exécuter un script bash et déplacer ou copier les fichiers répertoriés dans le fichier texte vers un autre répertoire.

Y at-il un moyen facile de le faire? Toutes suggestions ou ressources seraient grandement appréciées.

36
Jestep

rsync a plusieurs options qui peuvent prendre une liste de fichiers à traiter (--files-from, --include-from, etc.).

Par exemple, cela fera l'affaire:

rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
28

Afin d'éviter une utilisation inutile de cat (et si vous n'utilisez pas rsync):

xargs -a file_list.txt mv -t /path/to/dest

Cela gérera tout nom de fichier valide, sauf s'il contient une nouvelle ligne, si les fichiers sont répertoriés un par ligne.

for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

en supposant que bash, plus listoffiles contenant un fichier par ligne. Ma seule objection à la route rsync est que l'OP demande une méthode pour déplacer les fichiers, pas pour les copier. rsync a plus de drapeaux qu'un mariage royal, donc je suis sûr qu'il peut être modifié pour le faire, mais parfois plus simple est mieux!

15
MadHatter
rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync présente l'avantage supplémentaire par rapport aux commandes cp ou mv car il crée automatiquement des dossiers s'ils n'existent pas.

5
Paul Wenzel

Cela dépend du format du fichier texte dont vous disposez. Par exemple, si vous avez écrit la liste des fichiers de telle sorte que chaque fichier se trouve sur une nouvelle ligne. Vous pouvez utiliser des xargs comme:

$ cat your_text_file | xargs cp -t /path/to/destination

Vous pouvez également utiliser la commande find avec -exec option. pour copier/déplacer les fichiers.

4
Khaled

Si (et seulement si), vous n'avez aucun caractère désagréable dans les noms de fichiers (espaces, sauts de ligne, ce qui pourrait confondre les xargs sur la façon de diviser les choses en arguments individuels), et vous générez une liste de fichiers séparés par des sauts de ligne (un fichier par ligne), vous pourriez faire quelque chose comme.

cat filenames.txt | xargs mv -t /path/to/move/files/to

(En général, voir man xargs , c'est génial)

Si votre mv particulier n'a pas l'option -t, vous pouvez également faire quelques trucs comme

( cat filenames.txt; echo; echo /path/to/move/files/to ) | xargs mv

Remarque - aucun de ces éléments ne fonctionnera comme prévu s'il se trouve qu'il y a des noms de fichiers contenant des retours à la ligne.

2
Kjetil Joergensen

Je pense que la réponse rsync est meilleure, mais juste pour une autre option:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)
2
jj33

J'ai accidentellement copié le contenu complet d'un répertoire dans un répertoire de destination au lieu de déplacer le répertoire complet. Cela a abouti à un répertoire de destination encombré au lieu du répertoire d'origine ajouté au répertoire.

Pour résoudre ce problème, j'ai fait ce qui suit:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove La commande ci-dessus crée le fichier filestomove qui sera une liste de tous les contenus du répertoire de destination, triés par heure en sens inverse, du plus ancien au plus récent.

Ensuite, j'ai créé un sous-répertoire du répertoire de destination maintenant encombré pour y déplacer le contenu.

mkdir /path/to/cluttered/destination/directory/newsubdirectory

Ensuite, j'ai répété la liste du répertoire, sauf la liste à l'écran et en montrant plus de détails.

ls -lrht /path/to/cluttered/destination/directory/ Cette ligne répertorie le répertoire, trié par date en ordre croissant (tri inverse par heure) et affiche plus d'informations, y compris l'horodatage de chaque fichier dans le répertoire de destination maintenant encombré. Je fais référence à cela, en commençant par le haut pour montrer quels répertoires et fichiers je veux garder où ils étaient. Il y aura un écart dans l'horodatage des fichiers où tous les nouveaux fichiers commencent qui ne devraient pas y être.

Ensuite, j'ai édité le fichier filestomove créé à la première étape ci-dessus (qui est trié par date) et supprimé les quelques éléments de la liste qui existaient précédemment que je souhaite conserver dans le répertoire d'origine.

vim /opt/dircheck/filestomove Supprimer en haut, tous les fichiers que vous ne souhaitez pas déplacer.

Ensuite, j'ai utilisé la commande répertoriée précédemment dans ce message pour déplacer les fichiers de ma liste vers le nouveau répertoire que j'ai créé.

Sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

Cela a déplacé tous les fichiers en une fraction de seconde. (Remarque: il se peut que vous n'ayez pas besoin du Sudo au début, c'est une question d'autorisations de fichiers).

Maintenant, mon répertoire de destination d'origine est agréable et propre et contient un nouveau répertoire avec tous les fichiers et répertoires qui l'encombraient.

1
John

Essayez quelque chose comme:

cat list.txt | while read line; do mv "$line" /images; done
0
AliGibbs

Ce qui suit a fonctionné pour moi où j'avais besoin de copier tous les fichiers PNG d'un chemin spécifique (et tous les sous-répertoires) vers un nouvel emplacement tout en préservant la structure du répertoire:

rsync -av --Prune-empty-dirs --include='*/' --include='*.png' --exclude='*' source/ destination/

Étant donné que RSYNC crée d'abord le miroir de la structure de répertoires, puis synchronise les fichiers, vous pouvez vous retrouver avec des dossiers excédentaires vides. J'ai utilisé l'indicateur --Prune-empty-dirs pour supprimer ces répertoires vides.

Je n'ai aucune affiliation, mais j'ai cru bon de donner du crédit à la source qui a inspiré cette solution: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/

0
John Mark Mitchell