Jak usunąć końcowe znaki w nazwach plików w Bash?

13

Mam kilka plików multimedialnych, takich jak te poniżej:

tvshow.s01e11]Bloodlines.avi
tvshow.s01e12]suffer.avi
tvshow.s01e13]NotMe.avi

Chciałbym zmienić ich nazwę na

tvshow.s01e11.avi
tvshow.s01e12.avi
tvshow.s01e13.avi

Próbowałem użyć zmiany nazwy, ale najwyraźniej nie otrzymałem właściwej składni, ponieważ się nie udaje.

Widgeteye
źródło
Jeśli kiedykolwiek chcesz to zrobić w GUI, krenamejest cudownie. Ma wiele potężnych opcji i pokazuje, co zrobi, zanim faktycznie to zrobi. Możesz nawet użyć go do przetestowania wzorców, których możesz użyć później.
Joe

Odpowiedzi:

14

W powłoce można po prostu:

for x in *]*.avi ; do 
    mv -i "$x" "${x%]*.avi}.avi"
done

Powłoka może wygenerować listę nazw plików za pomocą zwykłego globu i ${var%pattern}usuwa (najkrótszy) pasujący wzorzec z końca łańcucha w zmiennej var. Ponieważ ostateczne rozszerzenie jest zawsze .avi, właśnie usunąłem go ze wzorem i dodałem z powrotem. W przypadku cudzysłowów powinno to również działać z nazwami plików zawierającymi spacje, npFancy Name for a Show.s01e01]Asdf.avi

ilkkachu
źródło
@NoviceC wzorzec extglob nie był złym pomysłem. Właściwie coś takiego ${x/]*([^.])}powinno zrobić, usuwa nawias i dowolną liczbę kropek. (choć zawodzi, jeśli są inne nawiasy
kwadratowe
Trafne spostrzeżenie. Ale tak naprawdę po prostu skomplikowałem ten problem, kiedy powinienem był pójść ${x/]*.avi}i właśnie dodałem .avipodobnego do ciebie. Ale byłem również niezadowolony z tego, jak odstępy w nazwie będą się łamać (`find . -name '*]*.avi'`). Z przyjemnością udostępniłem ograniczoną standardową metodę polecenia unix, ponieważ zmiana nazwy nie jest, ale to wydmuchuje moje z wody.
Nowicjusz C
2

Jest to wszelkiego rodzaju niepraktyczne - inne odpowiedzi są znacznie szybsze i krótsze - ale ...

Możesz użyć PowerShell! Microsoft niedawno go pozyskał i udostępnił na wielu platformach. Aby uzyskać instrukcje dotyczące pobierania i instalacji systemu operacyjnego, zobacz sekcję „Pobierz PowerShell” .

Po zainstalowaniu możesz użyć tego krótkiego skryptu:

Get-ChildItem -File '*]*.avi' | ForEach-Object {
    Rename-Item $_ -NewName (($_.Name -Split ']')[0] + '.avi')
}

Zasadniczo, przechodzi przez każdy obiekt w bieżącym katalogu, który jest dopasowaniem pliku *]*.avi, pobiera część przed nawiasem, wkleja z .avipowrotem do niego i przypisuje to jako nową nazwę.

Aby uruchomić go bezpośrednio z Bash, użyj tego częściowo golfowego jedno-liniowego:

powershell -command $'gci -File \'*]*.avi\'|%{rename-item $_ -NewName (($_.Name -Split \']\')[0]+\'.avi\')}'

Cytuj ucieczkę dzięki uprzejmości tej odpowiedzi Przepełnienie stosu .

(Testowane w Bash na Ubuntu w systemie Windows. Prawdopodobnie jest to znacznie krótszy sposób korzystania z PowerShell, ale chciałem pokazać coś, co jest zrozumiałe dla osób, które nie znają wyrażeń regularnych.)

Ben N.
źródło
Rube Goldberg byłby dumny! Regeksy to prawdziwa PITA do nauczenia się, ale warto wiele razy - nawet na podstawowym poziomie, w którym mogę ich używać.
Joe
1

Debian ma pakiet o nazwie mmv, który może być również dostępny w innych dystrybucjach i powinien być wystarczająco łatwy do skompilowania ze źródła, jeśli nie. Pozwala napisać to:

mmv '*]*.avi' '#1.avi'

Możesz przeczytać stronę podręcznika systemu Ubuntu dla tego polecenia, aby uzyskać więcej informacji.

MvG
źródło
0

Spowoduje to wyszukanie wzoru i zastąpienie tekstu za pomocą sed.

 $sed 's/\(.*]\)[a-zA-z0-9].*\(.avi\)/\1\2/' filename
Tejender Mohan
źródło