Używanie zmiany nazwy, utrzymanie części wyrażenia regularnego wyszukiwania

8

Ranek,

Obecny projekt, nad którym muszę pracować, miał poprzedni schemat nazewnictwa, który mnie niepokoi ...

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

Powiedziano mi, że „a” w wersji ma identyfikować wersje „alfa”, które wymagają więcej pracy. Na tym etapie projektu mogę usunąć „a” i zastąpić go „.1” (v2a -> v2.1).

Istnieje wiele plików, poza tym, co chcę zrobić ręcznie.

Wiem, że mogłem użyć polecenia rename, aby zmienić nazwy wszystkich plików jednocześnie, ale mam problem z tym, jak to zrobić. Jeśli użyję czegoś takiego:

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

wtedy stracę ostatnią cyfrę numeru wersji. Czy istnieje jakiś sposób, aby zmienić nazwę (lub inne narzędzie wiersza poleceń) zapamiętywać część wyrażenia regularnego użytego do znalezienia pliku? Tak więc „[0-9] a” na „[0-9] .1” zmieniłoby 1a na 1.1, a 4a na 4.1 itd.

drzemał
źródło
To zły pomysł. Zwykle v2a < v2 < 2.1. Innymi słowy wersja two-alpha reprezentuje wersję prowadzącą do wersji drugiej, a nie wersję późniejszą. Lepiej byłoby zmienić nazwę na wersję 1.99lub coś podobnego.
jpaugh

Odpowiedzi:

15

Możesz użyć grup przechwytywania :

$ 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

Lub możesz użyć wyglądu :

$ 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

Lub, podobnie do lookbehind, twierdzenie o zerowej długości \K, co oznacza „zapomnij wszystko dopasowane do tego momentu”:

$ 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

Zauważ, że użyłem krótszego \dzamiast [0-9]. Te dwa są równoważne, ale renamejest to skrypt perla, więc rozumie składnię wyrażeń regularnych zgodnych z Perlem (PCRE).

Zauważ, że zmieni to tylko pierwsze wystąpienie liczby, po której następuje a. To może, ale nie musi być to, czego potrzebujesz, w zależności od nazw plików.

Te -nmarki renamepokazać, co by to zrobić bez faktycznie robi nic. po potwierdzeniu, że działa zgodnie z oczekiwaniami, usuń go, aby faktycznie zmienić nazwy plików.

terdon
źródło
8

Zmodyfikuj polecenie w ten sposób:

rename 's/([0-9])a/$1.1/' *
  • Polecenie podstawienia s/<souce>/<replacement>/zastąpi ciąg źródłowy (który może być wyrażeniem regularnym) ciągiem zastępującym.
  • Grupy przechwytywania - te części łańcucha źródłowego, które są zamknięte w nawiasach: (regexp), (string)itp zostaną przypisane jako wartości kolejnych zmiennych $1, $2itd ..
  • Tak więc w ciągu zastępującym zmienna $1zostanie rozwinięta z jej wartością, która w tym przypadku musi pasować do wyrażenia regularnego [0-9].
pa4080
źródło