Lot renommer des fichiers

151

J'ai un répertoire plein d'images:

image0001.png
image0002.png
image0003.png
...

Et je voudrais un one-liner pour les renommer (par exemple).

0001.png
0002.png
0003.png
...

Comment puis-je faire cela?

Homme Internet
la source
8
C'est l'une des principales FAQ Unix en ligne de commande, et je ne la trouve pas déjà sur ce site. Devrions-nous donc créer ce Wiki de la communauté?
Gilles
5
Je ne vois pas pourquoi. C'est une question spécifique avec une réponse vérifiable.
Internet man
3
Si vous utilisez X, cela n’est pas plus facile que thunar -B *.pngpour l’outil d’affichage graphique en vrac de renommée de thunar.
dotjoe
@dotjoe Merci, Thunar est vraiment intéressant.
Volker Siegel

Réponses:

107

Si vous utilisez Bash ou un autre shell compatible POSIX:

for f in *.png; do
    mv -- "$f" "${f#image}"
done
W_Whalley
la source
2
C’est l’une des méthodes de substitution de paramètres présentée dans le guide de script Bash de Mendel Coopers Advanced tldp.org/LDP/abs/html
W_Whalley du
2
@W_Whalley Je recommande fortement d' éviter ce guide, en faveur du Wooledge Bash Guide .
Wildcard
@Wildcard: pour quelles raisons évitez-vous le guide ABS?
Christian Severin
@ChristianSeverin promotion des mauvaises pratiques et des codes brisés. Vérifiez les liens sur ma page de profil.
Wildcard
Si vous ne savez pas comment adapter cet exemple à différents modèles de fichiers, vous pouvez jeter un œil à la section Extension de paramètres du guide mentionné ci-dessus.
lex82
108

Sur Debian et ses dérivés, Perl renamefonctionne de la même manière sed:

  rename -v 's/image//' *.png

Il y a aussi le renamede util-linuxqui fonctionne comme ça, à la place:

  rename image '' *.png
Homme Internet
la source
6
vous devriez vraiment expliquer qu'il s'agit d'un programme Perl qui doit éventuellement être installé et qu'il utilise des expressions régulières comme argument.
Ah, je n'étais pas au courant de ça. Je donnerai crédit à la réponse canonique, quand je l'identifierai :)
Internet man
5
Ce renameprogramme est issu d'une distribution d'exemples Perl. Debian et Ubuntu l’envoient en tant que /usr/bin/rename. D'autres variantes d'Unix peuvent ne pas le fournir, ou peuvent fournir un complètement différent /usr/bin/rename.
Gilles
1
Certaines versions de renameprendre un de la structure de remplacement:rename [options] <expression> <replacement> <file>...
mêle
1
Si vous utilisez un système basé sur Debian, sudo apt-get install rename, vous pouvez utiliser la commande rename. C'est sed pour les noms de fichiers.
ctrl-alt-delor
41

zmv

Le shell zsh a une commande de renommage par lot puissante appelée zmv.

Vous devez d’abord activer la zmvcommande comme suit (cela peut aller dans votre ~/.zshrc).

autoload zmv

La syntaxe de base est zmv PATTERN REPLACEMENT. Le motif est une expression de shell glob. Certaines parties du motif peuvent être entourées de parenthèses. Le texte de remplacement peut contenir $1, $2etc. pour faire référence au nième groupe de parenthèses du motif. Par exemple:

zmv 'image(*.png)' '$1'

Vous pouvez également demander zsh de définir automatiquement $1, $2etc. pour faire correspondre les caractères génériques dans le modèle:

zmv -w 'image*.png' '$1.png'
Gilles
la source
4
sweeeeeeeeeeeeeeeeeet. Encore une autre raison pour laquelle je devrais apprendre le zsh.
ixtmixilix
1
@ixtmixilix, que faut-il apprendre? Il suffit de commencer à l’utiliser et d’ajouter peut-être prezto ( github.com/sorin-ionescu/prezto ) pour encore plus de plaisir.
Gerry
Vraiment cool, comme l'a souligné l'homme de zmv, ceci peut être simplifié en ajoutant alias mmv = 'noglob zmv -W' à: mmv * .c.orig orig / *. C
Bretsko
L'activation de zmvprezto nécessite de supprimer la mise en commentaire de la ligne dans votre ~ / .zpreztorc après # Set the Zsh functions to load (man zshcontrib).avoir donnézstyle ':prezto:load' zfunction 'zargs' 'zmv'
33

J'utilise normalement l' utilitaire simple et convivial mmv ( page de manuel ) pour ce cas d'utilisation:

$ mmv "image*.png" "#1.png"

va effectuer votre tâche.

Le #1modèle dans la cible sera remplacé par tout ce qui correspond au caractère générique dans le modèle source. Cela fonctionne également pour plusieurs caractères génériques et peut être utilisé par exemple pour modifier l'ordre des parties de noms de fichiers. Vous pouvez aussi facilement faire des choses plus compliquées, comme convertir des minuscules en majuscules.

Assurez-vous de protéger les motifs de la coque en les citant.

Marcel Stimberg
la source
Merci de signaler cet utilitaire. Je l'ai trouvé dans les dépôts Debian, Ubuntu et Cygwin. J'ai eu des problèmes avec la page de manuel, mais j'ai trouvé quelques pages Web et cette question de débordement de pile qui m'a aidé à expliquer comment vous l'utilisiez. stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley
Merci, j'ai ajouté quelques informations supplémentaires à la réponse pour la rendre plus claire.
Marcel Stimberg
3
Je ne peux pas le voter suffisamment! C'est si simple et sympathique. Disponible pour OS X en homebrew.
Greg Dubicki
9

POSIX sh pour la boucle

Utilise sed pour renommer

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done
X Tian
la source
6

J'aime Perl donc:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

Vous pouvez également utiliser le même modèle pour d'autres tâches, telles que la copie des fichiers dans un autre répertoire:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'
gvkv
la source
2
Ou (plus sûr!):rename($old,$_)
reinierpost
5

qmv

La commande qmvde renameutilsouvre un éditeur affichant une liste de noms de fichiers avec deux colonnes séparées par un onglet. Chaque ligne affiche l'un des noms de fichiers, identique dans les deux colonnes. La colonne de droite représente les nouveaux noms des fichiers.
Pour apporter des modifications, éditez les noms sur le côté droit. Dans cet exemple, :%s/...le mode bloc visuel est utile.

Noms de fichiers dans votre éditeur

$ qmv *.png

En éditeur:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

Editer les noms dans la colonne de droite:
(Suppression du imagepréfixe de toutes les lignes en utilisant le mode bloc visuel)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

Journal de renommage:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(par exemple Ubuntu: apt-get install renameutils)

Volker Siegel
la source
3

récursif

Recurse facile en sélectionnant des fichiers image * png, et suppose qu'il n'est pas nécessaire de traiter les nouvelles lignes dans les noms de fichiers

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

Sûr, capable de gérer les espaces, les nouvelles lignes, les barres obliques inverses et tout le reste :

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done
X Tian
la source
1

POSIX sh utilisant une boucle while

Lire les noms de la findcommande.

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

Lire les noms d'un fichier

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist
X Tian
la source
1

Utilisation de l’ expansion d’accolades :

for N in {0001..1000}; do mv "{image,}$N.png"; done
αғsнιη
la source
1

Pour Windows et Linux , ce script Perl fera l'affaire. dans ce cas:

$ rnm -l 's/^image//' '*.png'

Le script peut être exécuté de manière récursive sous des répertoires et même ajouter un nombre à chacun d'eux:

$ rnm -r 's/^/$counter./' '/\.png$/'

Les caractères UTF-8 sont également traités correctement, à la fois sous Windows et sous Linux.

circulosmeos
la source
0

Vous pouvez utiliser cet outil: rnm ( page web )

Pour votre cas, la commande serait:

rnm -rs '/^image//' *.png

Vous pouvez trouver plus d'exemples / docs ici .

Jahid
la source
0

Essayez brename ( https://github.com/shenwei356/brename ), un outil pratique de ligne de commande multiplateforme pour renommer par lots des fichiers / répertoires en toute sécurité via des expressions régulières (prenant en charge Windows, Linux et OS X).

@patrickDurusau a déclaré:

Linux propose diverses options de changement de nom de fichier de traitement par lots, mais je n’ai pas constaté d’inconvénients dans brename qui m’échappait.

Fonctionnalités:

  • Multiplate-forme . Prise en charge de Windows, Mac OS X et Linux.
  • Coffre -fort En vérifiant les conflits et les erreurs potentiels .
  • Filtrage de fichiers . Prise en charge de l'inclusion et de l'exclusion de fichiers via une expression régulière. Pas besoin d'exécuter des commandes comme find ./ -name "*.html" -exec CMD.
  • Renommer la sous-correspondance avec la valeur correspondante via un fichier clé-valeur .
  • Renommer via un entier croissant .
  • Renommer récursivement les fichiers et les répertoires .
  • Soutenir la course à sec .
  • Sortie colorée .

Commander:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed
Wei Shen
la source
-5

ls * png | en lisant -rf; do f2 = "` echo $ f | sed -e's / image // '`"; mv $ f $ f2; terminé

Ivan P
la source
Quelque chose ne va pas: "mv: opérande manquant dans le fichier de destination après 'image0001.png'"
Internet Man
3
Il y a beaucoup de problèmes avec votre code. Analyser la sortie de lsappelle simplement des problèmes. readdevrait être read -r. toutes les substitutions de variables doivent être entre guillemets doubles.
Gilles
Vous pourriez écrire ceci plus efficacement en tant que for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. L'analyse lsn'est ni nécessaire ni bonne idée .
kojiro