Zmień nazwę plików za pomocą polecenia jednego wiersza

10

Mam ten katalog i chcę zmienić nazwę plików:

===> ls -1 Der-vierte-Weise/
10 - 10 - Erkenntniss.ogg
1 - 01 - Hoffnung.ogg
11 - 11 - Wahrheit.ogg
12 - 12 - Dankbarkeit.ogg
13 - 13 - Kredits.ogg
2 - 02 - Familie.ogg
3 - 03 - Demut.ogg
4 - 04 - Freude.ogg
5 - 05 - Schoenheit.ogg
6 - 06 - Solidaritaet.ogg
7 - 07 - Entscheidung.ogg
8 - 08 - Hilfe.ogg
9 - 09 - Unterstuetzung.ogg

Wynik powinien wyglądać następująco:

===> ls -1 Der-vierte-Weise/
01 - Hoffnung.ogg
02 - Familie.ogg
...

Chciałbym rozwiązać ten problem za pomocą popularnych narzędzi powłoki.

guettli
źródło
1
Chciałbym rozwiązać ten problem za pomocą popularnych narzędzi powłoki. Nie mówię, że nie masz dobrego powodu, ale ufam, że zadałeś i odpowiedziałeś sobie na pytanie „dlaczego?”. Ostatnim razem, gdy miałem bardzo podobny problem do rozwiązania, natychmiast odsunąłem Basha na bok i rozwiązałem go w Pythonie. O wiele łatwiej (ale znałem już Pythona, metody łańcuchowe, glob.glob i os.rename - i musiałem również rekurować drzewo pełne nazw folderów ze spacjami i innymi niezręcznymi znakami, z których żaden nie jest przyczyną dodatkowych kłopot, jeśli używasz Pythona)
nigel222
1
@ nigel222 Jestem leniwy i chcę wpisać jak najmniej znaków. Dlatego nie chcę tutaj używać Pythona. Nie zrozum mnie źle. Do tej pory Python jest moim preferowanym językiem programowania i używam go codziennie.
guettli

Odpowiedzi:

18

Możesz użyć rename...

rename -n 's/^[0-9]+ - //' *

Usuń -npo przetestowaniu, aby faktycznie zmienić nazwę plików

Wyjaśnienie

  • s/old/new/wymienić oldznew
  • ^ początek łańcucha
  • [0-9]+ niektóre liczby
Zanna
źródło
jaki rodzaj wyrażeń regularnych jest obsługiwany przez renamenarzędzie. Czy używa PCRE? ... byłoby wspaniale.
guettli
5
@ guettli ściśle mówiąc, nie, to nie jest PCRE (to wyrażenia regularne zgodne z Perlem ). Jest renameto skrypt Perla, więc ma pełną obsługę wyrażeń regularnych Perla; PCRE jest tylko jego podzbiorem. Jednak wszystko, co znasz z PCRE, będzie miało zastosowanie rename.
terdon
@terdon Nie dbam o wdrożenie. Jeśli spojrzysz na to za pomocą okularów matematycznych, to renamema wyrażenia regularne zgodne z Perlem. Tak, implementacja pcre nie jest używana. Zrozumiałem to :-) Dziękuję za szybką odpowiedź.
guettli
9

bash rozszerzenie parametru, aby usunąć wymaganą część od początku:

for f in *[[:blank:]]*.ogg; do echo mv -i -- "$f" "${f#[[:digit:]]*-[[:blank:]]}"; done

Rozszerzona forma:

for f in *[[:blank:]]*.ogg; do 
    echo mv -i -- "$f" "${f#[[:digit:]]*-[[:blank:]]}"
done

echojest przeznaczony do pracy na sucho; pozbądź się go do faktycznego działania:

for f in *[[:blank:]]*.ogg; do mv -i -- "$f" "${f#[[:digit:]]*-[[:blank:]]}"; done

Przykład:

% ls -1
1 - 01 - Hoffnung.ogg
2 - 02 - Familie.ogg

% for f in *[[:blank:]]*.ogg; do mv -i -- "$f" "${f#[[:digit:]]*-[[:blank:]]}"; done 

% ls -1                                                                             
01 - Hoffnung.ogg
02 - Familie.ogg
heemayl
źródło
Tak, działa. Dziękuję Ci. Ponieważ znam zgodne z Perlem wyrażenie regularne z Pythona (którego używam codziennie), wolę renamepolecenie. (Wymagane mniej pisania).
guettli
1
@guettli renameto droga, jeśli znasz PCRE; renameodpowiedź została już podana więc trzeba przenieść z czystym bash. Wystarczy zauważyć, python„s re(lub regex) moduł nie jest w pełni kompatybilny PCRE BTW.
heemayl
@ guettli Czy również oceniłeś moją odpowiedź? : O
heemayl,
Tak zrobiłem i głosowałem za twoim komentarzem. Mam nadzieję, że nie bierzesz tego osobiście. Nie zrozum mnie źle, ale moim osobistym zdaniem jest to ${f#[[:digit:]]*-[[:blank:]]}brzydkie. Tak to działa. Ale żyjemy w 21 wieku. Myślę, że czas przejść z „działa” na „to łatwe i przyjemne”. Jeśli celem jest „to działa”, to linux nigdy nie straci uprzedzeń, że nie jest przyjazny. Ponieważ masz już dużo głosów oddanych, ten jeden głos oddany nie powinien zaszkodzić (mam nadzieję). Jeśli tak, powiedz mi, a ja to cofnę.
guettli
1
@guettli Cokolwiek Ci odpowiada. Tutaj: gnu.org/software/bash/manual/html_node/... Uwaga: klasa postaci [[:digit:]]i [[:blank:]]tam, aby spełnić twoje wymagania locale, są również dość powszechne w Regex.
heemayl