web-dev-qa-db-fra.com

Utiliser renommer, en gardant une partie de l'expression rationnelle

Matin,

Le projet actuel sur lequel je dois travailler avait un schéma de nommage précédent qui me dérange ...

Base.v2.c
Base.v2a.c
Slider.v4a.h
Area.v2a.2.h

On m'a dit que le "a" dans la version était d'identifier les versions "alpha" qui nécessitaient davantage de travail. À ce stade du projet, je peux supprimer le "a" et le remplacer par un ".1" (v2a -> v2.1).

Il y a beaucoup de fichiers, au-delà de ce que je suis disposé à faire manuellement.

Je sais que je pourrais utiliser la commande rename pour renommer tous les fichiers à la fois, mais je ne sais pas comment le faire. Si j'utilise quelque chose comme:

rename 's/[0-9]a/.1/' *

alors je perdrai le dernier chiffre du numéro de version. Existe-t-il un moyen de faire renommer (ou un autre outil de ligne de commande) une partie de la regex utilisée pour rechercher le fichier? De sorte que "[0-9] a" à "[0-9] .1" change de 1a en 1.1, et de 4a en 4.1, etc.

8
swood

Vous pouvez soit utiliser groupes de capture :

$ rename -n 's/(\d)a/$1.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h

Ou vous pouvez utiliser un lookbehind :

$ rename -n 's/(?<=\d)a/.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h

Ou, semblable à un lookbehind, l'assertion de longueur 0 \K, qui signifie "oublie tout ce qui correspond jusqu'à ce point":

$ rename -n 's/\d\Ka/.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h

Notez que j'ai utilisé le \d plus court au lieu de [0-9]. Les deux sont équivalents, mais rename est un script Perl et comprend donc la syntaxe des expressions régulières compatibles Perl (PCRE).

Notez que cela ne fera que changer la première occurrence d'un nombre suivi d'un a. Cela peut être ou ne pas être ce dont vous avez besoin, en fonction de vos noms de fichiers.

Le -n fait en sorte que rename montre ce qu'il ferait sans rien faire. Une fois que vous avez confirmé qu'il fonctionne comme prévu, supprimez-le pour modifier les noms de fichiers.

15
terdon

Modifiez la commande de cette manière:

rename 's/([0-9])a/$1.1/' *
  • La commande de substitution s/<souce>/<replacement>/ remplacera la chaîne source (qui pourrait être une expression régulière) par la chaîne de remplacement.
  • Les groupes de capture - les parties de la chaîne source entourées de crochets: (regexp), (string), etc., seront attribuées en tant que valeurs de variables successives: $1, $2, etc.
  • Ainsi, dans la chaîne de remplacement, la variable $1 sera développée avec sa valeur, qui dans ce cas doit correspondre à l'expression rationnelle [0-9].
8
pa4080