Renommer les fichiers par lots en ligne de commande et Xargs
j'ai Donc la structure suivante:
.
..
a.png
b.png
c.png
j'ai lancé une commande pour les redimensionner
ls | xargs -I xx convert xx -resize xx.jpg
Maintenant mon dir ressemble à ceci
.
..
a.png.jpg
a.png
b.png.jpg
b.png
c.png.jpg
c.png
la première question Est, Comment puis-je renommer le fichier de sorte que je ne puisse avoir qu'une extension. Pas deux. (en gros, comment je nettoie mon erreur d'origine)?
La deuxième question est, à l'avenir, d'utiliser xargs, Comment puis-je changer l'extension du fichier simular en second command?
6 réponses
Comment puis-je renommer le fichier pour que je ne puisse avoir qu'une extension.
cd dir/with/messedup/files
for file in *.png.jpg; do
mv "$file" "${file%.png.jpg}.jpg"
done
dans l'avenir, en utilisant xargs, comment puis-je changer l'extension du fichier similaires à la deuxième commande?
à ma connaissance, cela ne peut pas être fait. La meilleure façon de le faire serait d'utiliser une boucle for avec substitution de paramètre semblable à celle ci-dessus:
for file in *.png; do
convert "$file" -resize "${file%.png}.jpg"
done
Si vous avez des fichiers dans des sous-répertoires que vous voulez convertir, puis vous pouvez pipe find
while read
boucle:
find . -type f -name '*.png' |
while read file; do
convert "$file" -resize "${file%.png}.jpg"
done
NOTE: c'est généralement considéré comme un mauvaise idée pour utiliser la sortie de ls
dans un script shell. Bien que votre exemple ait peut-être bien fonctionné, il y a beaucoup d'exemples où il n'a pas fonctionné. Par exemple, si vos noms de fichiers contiennent des newlines (ce que permet unix),ls
n'échappera probablement pas à ceux-là pour vous. (Cela dépend en fait de votre mise en œuvre, qui est une autre raison de ne pas utiliser ls
dans les scripts; son comportement varie grandement d'une boîte à l'autre.) Vous obtiendrez des résultats plus cohérents si vous utilisez find
dans un tout-lecture en boucle ou d'un fichier d'expansion (par exemple,*.png
) dans une boucle for.
cela peut aussi être fait avec xargs
et sed
pour changer l'extension de fichier.
ls | grep \.png$ | sed 'p;s/\.png/\.jpg/' | xargs -n2 mv
Vous pouvez imprimer le nom de fichier d'origine avec ce que vous voulez que le nom de fichier. Puis xargs utilise ces deux arguments dans la commande move. Pour la doublure, j'ai aussi ajouté un grep pour filtrer tout ce qui n'est pas un *.fichier png.
fin de la partie, mais voici comment vous pouvez renommer les fichiers avec xargs. Disons que vous avez un tas de fichiers nommés fileN.svg.png et vous voulez les appeler fileN.png où N pourrait être une série d'entiers:
ls *.svg.png | xargs basename -s .svg.png | xargs -I {} mv {}.svg.png {}.png
le premier xargs utilise le nom de base pour enlever les deux .svg et .png pour obtenir une juste filenameN
. Le second xargs reçoit ce nom nu et utilise le remplacement pour renommer le fichier.
pour corriger votre erreur, essayez le rename
utilitaire. Vérifiez la page de manuel pour plus de détails.
Dans votre cas, vous feriez rename '.png.jpg' '.jpg' ./*
si votre répertoire courant est défini correctement.
Puisque vous avez convert
disponible, je suppose que vous avez mogrify
(imagemagick
suite). Chaque fois que je veux faire cela, je copie les fichiers dans un répertoire différent et j'utilise mogrify
à la place. Je n'en ai généralement besoin que pour redimensionner, mais si vous changez le format de l'image aussi, mogrify
va gérer le noms de fichiers (créer de nouveaux fichiers avec les noms de fichiers appropriés).
vous l'utiliseriez comme mogrify -format jpg -resize [size] ./*.png
. Je ne suis pas sûr de ce que -resize
sans arguments de géométrie est censé faire l'affaire. Il n'est pas documentée et ne fonctionne pas sur ma machine.
comme le raisonnait Tim Pote, je ne pense pas que vous puissiez faire des xargs traiter les noms de fichiers et les extensions séparément.
je suis en retard à cette fête d'environ 3 ans, je viens d'avoir un problème similaire que j'ai moi-même résolu. J'avais une liste de fichiers png que j'ai convertis en utilisant inkscape, parce que le support svg D'ImageMagick est mauvais.
j'ai d'abord converti en faisant:
find . -name "*.svg" -exec inkscape {} --export-png={}.png
ce Qui bien sûr conduit à la même question, comme affiché ci-dessus.
file1.svg
file1.svg.png
file2.svg
file2.svg.png
file3.svg
file3.svg.png
file4.svg
file4.svg.png
je voulais renommer *.svg.png *.png, c'est ce que j'ai fini par faire...
find . -name "*.svg.png" -print0 | sed 's/.svg.png//g' | xargs -0 -I namePrefix mv namePrefix.svg.png namePrefix.png
Cela fait trois choses:
- trouvez dans ce répertoire les fichiers nommés *.svg.png, le-print0 imprime à la sortie standard
- sed modifie la sortie standard, essentiellement l'échange .svg.png avec rien, donc j'aimerais obtenir: fichier1/fichier2/fichier3/fichier4
- xargs -0 pour obtenir les données à partir de sed, -je renvoie le nom du fichier avec l'extension, puis mv nom du fichier original à nouveau nom du fichier. Le mot namePrefix n'est pas quelque chose de spécial, je voulais juste le faire clair.
EDIT
je me rends compte maintenant que c'est la façon la plus alambiquée de le faire. On peut simplement utiliser la commande renommer.
rename 's/svg\.png/.png/' *
ma solution est similaire à de nombreuses solutions xarg, et particulièrement similaire à celle de Schleis.
la différence ici est une manipulation regex complète avec des références de correspondance, et des commandes sed qui ignorent correctement les fichiers qui ne correspondent pas donc vous n'avez pas besoin de préfiler votre liste.
ceci est également sûr pour les fichiers avec des espaces et des méta shell.
Modifier dans le remplacement de n'importe quel extension.
ls |
sed -nE 's/Rick\.and\.Morty\.(S03E[0-9]{2})\..*(\.[a-z0-9]{3})/"&" "Rick and Morty "/;T;p' |
xargs -n 2 mv
Explication
-n
arg dire sed à ne pas effectuer d'impression par défaut, le T
commande dit passez à la fin du script si la précédente s
le commandement n'a pas fait de remplacement, le p
la commande affiche l'espace de motif (seulement si le s
correspond à la commande).
&
dans le remplacement est une référence au contenu de la nom de fichier original de match.
si nous remplaçons mv
dans la commande bash -c 'echo "run($#) $@"' bash
ensuite, nous pouvons voir le nombre de fois mv
serait appelé, et avec le nombre et la valeur des paramètres:
$ ls |
sed -nE 's/Rick\.and\.Morty\.(S03E[0-9]{2})\..*(\.[a-z0-9]{3})/"&" "Rick and Morty "/;T;p' |
xargs -n 2 bash -c 'echo "run($#) $@"' bash
run(2) Rick.and.Morty.S03E02.720p.HDTV.x264-BATV.mkv Rick and Morty S03E02.mkv
run(2) Rick.and.Morty.S03E03.720p.HDTV.x264-BATV.mkv Rick and Morty S03E03.mkv
run(2) Rick.and.Morty.S03E04.720p.HDTV.x264-BATV.mkv Rick and Morty S03E04.mkv
run(2) Rick.and.Morty.S03E05.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E05.mkv
run(2) Rick.and.Morty.S03E06.720p.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E06.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E07.720p.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E07.mkv
run(2) Rick.and.Morty.S03E08.720p.HDTV.x264-BATV.mkv Rick and Morty S03E08.mkv
run(2) Rick.and.Morty.S03E09.720p.HDTV.x264-BATV.mkv Rick and Morty S03E09.mkv
run(2) Rick.and.Morty.S03E10.720p.HDTV.x264-BATV.mkv Rick and Morty S03E10.mkv