Oparta na wzorach, zmiana nazwy pliku wsadowego w terminalu

48

Muszę zmienić nazwę:

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

w

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

Jak to zrobić za pomocą jednej prostej linii poleceń terminalu?

Unamata Sanatarai
źródło
1
Odporna na błędy regexowa

Odpowiedzi:

79

Rozwiązanie powyższego przykładu przy użyciu zmiany nazwy :

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

Stosowanie:

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

Od man rename:

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

zmiana nazwy MOŻE przyjąć wyrażenia regularne jako argumenty.

Patrzymy na treść między pojedynczymi cytatami '. Możesz umieścić regex oddzielone przez /.

Formuła: s/(1)/(2)/gdzie (1)= wzór wyszukiwania i (2)= zamień wzór.

Więc zapoznania youself z regex , i cieszyć się zmiany nazwy pliku wsadowego wzór oparty!

Unamata Sanatarai
źródło
14
Wiem, że to Ubuntu, ale jeśli ktoś tu trafi, mimo że szukał rozwiązania OS X (zrobiłem to), renamełatwo go zainstalować brew install rename.
sandstrom
W Ubuntu 18.10 --no-actflaga jest --nonozamiast tego. Ta odpowiedź może być również nieco bardziej wyraźna: [files]odnosi się do początkowego pliku pasującego do wzorca w bieżącym katalogu, który chce się potencjalnie zmienić (np. *Pasuje do wszystkiego, ale tylko w bieżącym katalogu).
Patrick Dark
Twój link wskazuje na inny rename, który ma format rename from to filei nie obsługuje wyrażeń regularnych. W rzeczywistości moja dystrybucja Linuksa (Cent OS 7) ma dokładnie tę wersję.
Alex Che
6

jeśli pliki znajdują się w katalogach częściowych, użyj zmiany nazwy po znalezieniu, np .:

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

-n po zmianie nazwy ma przetestować, usuń ją, aby kontynuować! -)

w ten sposób kojarzysz znajdowanie i zmianę nazwy mocy.

Osobiście użyłem go do zmiany nazwy nagłówka źródeł .h na .hpp

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;
bcag2
źródło
Jest dokumentacja dla -iname, -typeoraz -execflagi w manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression . ( find --helpnie jest to szczególnie pomocne w przypadku tego polecenia.) TL; DR: -inamedopasowuje wzór bez rozróżniania wielkości liter; -type fdopasowuje „zwykłe pliki”; i -execwykonuje wyrażenie, dopóki nie napotka ;znaku (średnika).
Patrick Dark
5

Można tego dokonać z niewielką magią rozszerzania parametrów bash!

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

file_[0-9]*_*;- Pierwszy wzorzec służy do przechodzenia przez wszystkie pliki zaczynające się od „numer_pliku_”
${f#file_[0-9]*_}- Drugi wzorzec file_[0-9]*_jest używany w rozszerzaniu parametrów, który każe bashowi usunąć „numer_pliku_” z początku łańcucha.

Aby uzyskać więcej informacji na temat Parameter expansion:

man bash
Basharat Sialvi
źródło
Zauważ, że używa to globów, a nie wyrażeń regularnych, więc [0-9]*dopasuje jedną cyfrę, po której następuje dowolny ciąg. Prawdopodobnie jest lepszy sposób na dopasowanie tylko liczb, ale nie mogę wymyślić niczego zwięzłego.
wjandrea
Czy byłbyś również w stanie zasugerować sposób, aby to polecenie działało rekurencyjnie we wszystkich podkatalogach?
Francesco DM,