Basé sur un modèle, renommer le fichier batch dans le terminal


48

Je dois renommer ce qui suit:

file_001_loremipsum.png
file_002_dolor.png
file_003_sit.png
file_004_amet.png
file_105_randomness.png

dans

upl_loremipsum.png
upl_dolor.png
upl_sit.png
upl_amet.png
upl_randomness.png

Comment puis-je y arriver avec une seule ligne de commande de terminal?


1
Une version de python basée sur regex et sécurisée qui fonctionne de manière récursive sur tous les sous-dossiers: stackoverflow.com/a/39698169/191246
ccpizza

Réponses:


79

La solution à l'exemple ci-dessus, en utilisant rename :

rename -v -n 's/file_\d{1,3}/upl/' file_*.png

Usage:

rename [options] [Perl regex search/replace expression] [files]

De man rename:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

renommer PEUT prendre regex comme arguments.

Nous examinons le contenu entre les guillemets simples '. Vous pouvez placer les expressions rationnelles séparées par /.

Formule: s/(1)/(2)/(1)= modèle de recherche et (2)= remplacer le modèle.

Alors, familiarisez-vous avec regex et appréciez le changement de nom de fichier de lot basé sur un modèle!


14
Je sais que c’est Ubuntu, mais si quelqu'un finit ici même s’il cherchait une solution OS X (je l’ai fait), il renameest facile à installer avec brew install rename.
sandstrom

Dans Ubuntu 18.10, le --no-actdrapeau est à la --nonoplace. Cette réponse pourrait également être un peu plus explicite: [files]fait référence à un modèle initial de correspondance de fichiers dans le répertoire actuel que l’on souhaite potentiellement renommer (par exemple, *correspond à tout, mais uniquement dans le répertoire actuel).
Patrick Dark

Votre lien pointe vers un autre renamequi a un format rename from to fileet ne supporte pas les expressions régulières. En fait, ma distribution Linux (Cent OS 7) a exactement cette version.
Alex Che

6

si les fichiers sont dans plusieurs répertoires, utilisez renommer après une recherche comme:

find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

le -n après renommer est à tester, supprimez-le pour continuer! -)

comme cela, vous associez rechercher et renommer le pouvoir.

Personnellement, je l’ai utilisé pour renommer l’en-tête des sources .h en .hpp

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;

Il y a des documents pour la -iname, -typeet des -execdrapeaux à manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression . ( find --helpn'est pas particulièrement utile pour cette commande.) TL; DR: -inamecorrespond à un modèle sans distinction de casse; -type fcorrespond aux «fichiers normaux»; et -execexécute une expression jusqu'à ce qu'elle rencontre un caractère ;(point-virgule).
Patrick Dark

5

Cela peut être fait avec un peu de magie de l'expansion des paramètres bash!

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*;- Le premier motif est utilisé pour parcourir tous les fichiers qui commencent par 'file_anynumber_'
${f#file_[0-9]*_}- Le deuxième motif file_[0-9]*_est utilisé dans le développement de paramètres qui indique à bash de supprimer 'file_anynumber_' du début de la chaîne.

Pour plus d'informations sur Parameter expansion:

man bash

Notez que ceci utilise globs, pas regex, donc [0-9]*correspondra à un chiffre suivi de n'importe quelle chaîne. Il y a probablement une meilleure façon de faire correspondre les chiffres, mais je ne peux penser à rien de succinct.
Wjandrea

Seriez-vous également en mesure de suggérer un moyen de faire fonctionner cette commande de manière récursive dans tous les sous-répertoires?
Francesco DM
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.