J'ai des millions de fichiers avec la nomenclature suivante sur une machine Linux:
1559704165_a1ac6f55fef555ee.jpg
Les 10 premiers chiffres sont horodatés et ceux suivis d'un _
sont des identifiants spécifiques. Je souhaite déplacer tous les fichiers correspondant à des ID de nom de fichier spécifiques dans un dossier différent.
J'ai essayé cela sur le répertoire avec des fichiers
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
Cependant, je reçois une erreur indiquant:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Lorsque j'ai essayé, mv ??????????_a1ac*.jpg
je reçois une liste d'arguments trop longue. J'ai au moins 15 modèles de nom de fichier différents. Comment les déplacer.
| ??????????_a1ac*.jpg
:: bash le développe en plusieurs noms de fichier, le premier étant1559704165_a1ac6f55fef555ee.jpg
, si vous vous retrouvez , dans cette 2ème étape de pipe, en essayant d'exécuter1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename
:. Je suppose que vous avez plutôt essayé de filtrer sur ce nom de fichier (voir les réponses ci-dessous pour cela)Réponses:
Tu devrais utiliser:
maxdepth 1
Cela signifie donc que vous ne souhaitez rechercher dans le répertoire actuel aucun sous-répertoire.type f
signifie trouver uniquement les fichiers.name '??????????_a1ac*.jpg'
est un modèle qui correspond au fichier que vous recherchez.mv -t destination "{}" +
signifie déplacer les fichiers correspondants vers la destination. Ici+
ajoute de nouveaux fichiers correspondants au précédent comme:Ici abcd sont des fichiers différents.
la source
-t
s'agit d'une extension GNU et peut donc ne pas être disponible sur d'autres types de dérivés UNIX."{}"
, auquel cas je tiens à souligner qu'il{}
n'est pas développé par le shell et n'a pas besoin d'être cité. Le shell passe{}
pour trouver, et find le voit{}
et le remplace par des chemins d'accès. Find exec n'utilise pas l'analyseur shell et n'effectue pas de fractionnement de mots. Le citer ne fait pas de mal, c'est juste que la justification donnée est un peu inexacte.Votre commande,
Pipes la liste de tous les fichiers vers tous les fichiers!
fera l'affaire.
la source
Tu es très proche. Vous devez utiliser l'
-name
option pourfind
. Et n'oubliez pas de citer le motif.Donc
la source
-print0
comme dernier argument à la recherche (au lieu de la valeur par défaut: -print), et ajouter a-0
comme première option à xargs (ie :)xargs -0 mv -t "/home/ubuntu/ntest"
. de cette façon, toutes sortes de noms de fichiers étranges (avec des espaces dedans, avec "newline" dedans, etc.) peuvent être gérés.find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"
(fonctionne uniquement avec la recherche de type GNU, cependant)Pas aussi "bon" que les
find
solutions, mais une autre solution valable est de rendre lesmv
commandes plus granulaires.Cela fait 4096 mouvements, avec moins de fichiers déplacés par
mv
opération.la source
find
(pour une raison quelconque).Si vous souhaitez déplacer des fichiers sur le même système hôte, ce que je suppose que vous faites avec votre
mv
,rsync
pourrait être une option plus rapide:--inplace
et-W
sont configurés pour accélérer le processus.Si cela donne une autre liste d'arguments erreur trop longue, vous pouvez alimenter
rsync
Faites la liste avec find, par exemple
et donnez-le à
rsync
La source ici est
/path/to/files
, carrsync
traitera la liste que vous lui donnez par rapport à votre source.Le point étant:
rsync
est plus rapide quemv
si les fichiers ne sont pas sur le même système de fichiers .la source
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt
-à- dire puis la passer à rsync avec--files-from=/tmp/my_image_list.txt
. Le fait étant quersync
c'est plus rapide. Sauf si les fichiers résident sur le même système de fichiers, qu'OP n'a pas indiqué.