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?

Unamata Sanatarai
la source
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!

Unamata Sanatarai
la source
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/' {} \;
bcag2
la source
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
Basharat Sialvi
la source
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