Zmieniaj nazwy setek plików jednocześnie, aby uzyskać prawidłowe sortowanie


23

Mam mnóstwo plików, nazwane rzeczy jak 1.jpg, 2.jpg, 3.jpg, i tak dalej, aż do 1439.jpg, jednak mam problem z jednym z moich projektów i alphabetizing. Będzie to zwykle iść w kolejności 1.jpg, 10.jpg, 11.jpgi tak dalej.

Potrzebuję sposobu na nazwanie plików, aby były w takim formacie, jak do 00001.jpgsamego końca 01439.jpg.

Jak mógłbym to zrobić szybko i skutecznie?


To, czego szukasz, to „naturalne sortowanie”, może to pomoże: askubuntu.com/questions/41390/…
Fabian Blechschmidt

Odpowiedź, która nie jest bezpośrednią odpowiedzią? ls -v unix.stackexchange.com/questions/33909/…
WernerCD

+1, ponieważ próbowałem to zrobić bezskutecznie pyrenamer.
Parto

@FabianBlechschmidt, potrzebuję tego w programie, który nie jest na nautilus lub podobny. To jest dla indywidualnego projektu.
Kaz Wolfe

Myślę, że myślałeś o wdrożeniu naturalnego sortowania? Ale rozumiem, zmiana nazw plików jest dość łatwa, a jeśli to zadziała, świetnie :)
Fabian Blechschmidt

Odpowiedzi:


35

Ubuntu zawiera skrypt o nazwie rename. To tylko mały skrypt Perla, który oferuje wiele potężnych funkcji zmiany nazwy, ale najlepsza (w tym przypadku) jest możliwość uruchomienia Perla podczas wymiany. Rezultatem jest naprawdę kompaktowe rozwiązanie:

rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

Jest to podobne do innych printfodpowiedzi w tym stylu, ale wszystko jest załatwione dla nas. Powyższy kod dotyczy 5-cyfrowej liczby (w tym zmiennej liczby początkowych zer).

Przeszuka i zastąpi pierwszy znaleziony ciąg liczb wersją z zerowaniem i pozostawi resztę nazwy pliku w spokoju. Oznacza to, że nie musisz się zbytnio przejmować przenoszeniem jakiegokolwiek rozszerzenia lub prefiksu.

Uwaga: nie jest to całkowicie przenośne. Wiele dystrybucji używa rename.ulz util-linuxpakietu jako domyślnego renamepliku binarnego. Jest to znacznie zahamowana alternatywa (patrz man rename.ul), która nie zrozumie powyższego. Jeśli chcesz to zrobić na platformie, która nie używa nazwy Perla, dowiedz się, jak ją najpierw zainstalować.


A oto uprząż testowa:

$ touch {1..19}.jpg

$ ls
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg  3.jpg  5.jpg  7.jpg  9.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  2.jpg  4.jpg  6.jpg  8.jpg

$ rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

$ ls
00001.jpg  00005.jpg  00009.jpg  00013.jpg  00017.jpg
00002.jpg  00006.jpg  00010.jpg  00014.jpg  00018.jpg
00003.jpg  00007.jpg  00011.jpg  00015.jpg  00019.jpg
00004.jpg  00008.jpg  00012.jpg  00016.jpg

I przykładowe przedrostki (nie robimy nic innego):

$ touch track_{9..11}.mp3 && ls
track_10.mp3  track_11.mp3  track_9.mp3

$ rename 's/\d+/sprintf("%02d", $&)/e' *.mp3 && ls
track_09.mp3  track_10.mp3  track_11.mp3

Gdybym był Perlem, byłoby to idealne rozwiązanie. Naprawdę fajnie.
MGP

2
Nie używa żadnego perla, tylko dostarczone narzędzie, które jest już napisane w perlu.
Rob

1
W tym przypadku to nie dotyczyć jednego polecenia Perl, ale to nie jest dokładnie to, podnoszenia ciężkich. sprintfw Perlu zachowuje się podobnie jak sprintfw innych językach.
Oli

21
for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Edytować

Wyjaśnienie:

  • if [[ $f =~ [0-9]+\. ]] upewnia się, że zmieniane są nazwy tylko plików, których nazwy to liczby (po których następuje kropka).
  • printf "%.5d" NUMBER dodaje wiodące zera
  • "${f%.*}" wycina rozszerzenie (.jpg) i pozostawia tylko numer
  • .jpgpo drugim naciśnięciu wstecz ponownie dodaje rozszerzenie pliku.

Pamiętaj, że będzie to działać tylko w przypadku nazw plików, które są liczbami. Uzupełnianie lewych wiodących zer do plików nienumerowanych wymagałoby innego formatu.

Jeśli chcesz eksperymentować, wypróbuj to polecenie:

for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then echo mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Edytuj 2

Zwiększono bezpieczeństwo polecenia, upewniając się, że zmieniane są tylko nazwy plików, które są liczbami. Pamiętaj, że wszystkie istniejące pliki o nazwie jak 00001.jpg zostaną zastąpione.


Ten skrypt liniowy działa „po wyjęciu z pudełka” na Ubuntu i innych dystrybucjach Linuksa! 😃 Nie trzeba instalować żadnych dodatkowych narzędzi za pomocą Perla, Pythona itp.
HEXcube

6

Poniżej skryptu python.

Skrypt dodaje zera wiodące do określonej liczby cyfr. Jeśli nazwa jest większa, plik (nazwa) pozostaje nietknięty.

Łączenie różnych rozszerzeń w jedną akcję zmiany nazwy może być wygodniejsze. Aby dodać rozszerzenie (rozszerzenia), po prostu dodaj je na przykład do krotki extensions = (".jpg", ".jpeg", ".tiff").

Skopiuj tekst do pustego pliku, zapisz go jako rename.py, wprowadź poprawną ścieżkę do katalogu plików ( sourcedir), liczbę cyfr, które mają mieć nowe nazwy ( number_ofdigits) i rozszerzenia (nazwy extensions) plików, aby zmienić nazwę ( )

Uruchom go za pomocą polecenia:

python3 /path/to/script/rename.py

Scenariusz:

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; number_ofdigits = 5; extensions = (".jpg", ".jpeg")

files = os.listdir(sourcedir)
for item in files:
    if item.endswith(extensions):
        name = item.split("."); zeros = number_ofdigits-len(name[0])
        newname = str(zeros*"0")+name[0]+"."+name[1]
        shutil.move(sourcedir+"/"+item, sourcedir+"/"+newname)

edytować:

Poniżej nieco ulepszonej wersji. Automatycznie określa najdłuższą nazwę w katalogu i dodaje zera wiodące do długości najdłuższej nazwy.

przykład:

1.jpg
12.jpg
123.jpg

staje się:

001.jpg
012.jpg
123.jpg

Nie trzeba ustawiać liczby cyfr.

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; extensions = (".jpg", ".jpeg")
files = [(f, f[f.rfind("."):], f[:f.rfind(".")]) for f in os.listdir(sourcedir)if f.endswith(extensions)]
maxlen = len(max([f[2] for f in files], key = len))

for item in files:
    zeros = maxlen-len(item[2])
    shutil.move(sourcedir+"/"+item[0], sourcedir+"/"+str(zeros*"0")+item[0])

2

W Perlu zaimplementowano narzędzie zmiany nazwy, które bardzo ułatwia:

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

Pierwszy argument to wyrażenie Perla, które jest oceniane dla każdej nazwy pliku.


0

Istnieje GUI, które zrobi to o nazwie pyRenamer, które można znaleźć w repozytoriach. Zainstaluj, uruchom, wybierz katalog i po prostu ustaw „Wzorzec nazwy pliku” na „{num5}” na karcie „Wzory” i kliknij przycisk „Zmień nazwę”. Możesz także wyświetlić podgląd tego, co się stanie przed zmianą nazwy.


Podczas gdy Twoja odpowiedź DZIAŁA, pamiętaj, że jest to shell-scriptingsekcja, co oznacza, że ​​szukam odpowiedzi z linii poleceń. Czy możesz podać więcej szczegółów na temat programu? Na przykład, jaki jest format wzoru {num5}?
Kaz Wolfe

-4
for file in `(find * -maxdepth 1 -type f -name "*.jpg")`     
do    
  mv $file "000"$file    
done

Jest to prymitywne, ponieważ nie dokonuje inteligentnej zmiany nazwy, trzeba będzie wymyślić jakąś sztuczkę. Ale powinno ci to pomóc w sortowaniu.

Aktualizacja: Cóż, masz pełniejszą odpowiedź.


2
zmienia nazwę 1439.jpg na 0001439.jpg.
Avinash Raj

Tak, wiem, po prostu uzupełniałem dodatkowe zera, które powinny nadal działać z tym rodzajem.
Swarnendu Biswas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.