Wie entferne ich abschließende Zeichen in Dateinamen in Bash?

13

Ich habe eine Reihe von Mediendateien wie die folgenden:

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

Ich möchte sie in umbenennen

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

Ich habe versucht, umzubenennen, aber offensichtlich bekomme ich die Syntax nicht richtig, weil es fehlschlägt.

Widgeteye
quelle
Wenn Sie dies jemals in einer GUI tun möchten, krenameist es schön. Es hat alle Arten von leistungsstarken Optionen und zeigt Ihnen, was es tun wird, bevor es es tatsächlich tut. Sie können es sogar verwenden, um Muster zu testen, die Sie später in bash verwenden können.
Joe

Antworten:

14

In der Schale könnte man einfach tun:

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

Die Shell kann eine Liste der Dateinamen mit nur einem regulären Glob erstellen und ${var%pattern}das (kürzeste) übereinstimmende Muster vom Ende der Zeichenfolge in Variable entfernen var. Da die letzte Erweiterung immer ist .avi, habe ich sie einfach mit dem Muster entfernt und wieder hinzugefügt. Bei den Anführungszeichen sollte dies auch mit Dateinamen funktionieren, die Leerzeichen enthalten, wie zFancy Name for a Show.s01e01]Asdf.avi

ilkkachu
quelle
@NoviceC Das Extglob-Muster war keine schlechte Idee. Eigentlich sollte so etwas wie ${x/]*([^.])}tun, es entfernt eine Klammer und eine beliebige Anzahl von Nicht-Punkten. (schlägt jedoch fehl, wenn es andere Klammern oder Punkte gibt, da es nicht an das Ende der Zeichenfolge gesperrt ist)
ilkkachu
Das ist ein guter Punkt. Aber ich habe das Problem, bei dem ich hätte mitmachen sollen, wirklich nur überkompliziert ${x/]*.avi}und gerade ein .aviLike von dir hinzugefügt . Aber ich war auch unzufrieden damit, wie Leerzeichen im Namen aufbrechen würden (`find . -name '*]*.avi'`). Ich war froh, eine eingeschränkte Standard-Unix-Befehlsmethode zur Verfügung zu stellen, da Umbenennen nicht möglich ist, aber dies bringt meine Methode aus dem Wasser.
Anfänger C
2

Das ist alles andere als praktisch - die anderen Antworten sind viel schneller und kürzer - aber ...

Sie können PowerShell verwenden! Microsoft hat es kürzlich als Open-Source-Version bereitgestellt und plattformübergreifend gemacht. Download- und Installationsanweisungen für Ihr Betriebssystem finden Sie im Abschnitt "Get PowerShell" .

Sobald Sie es installiert haben, können Sie dieses kurze Skript verwenden:

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

Grundsätzlich durchläuft es jedes Objekt im aktuellen Verzeichnis, das einer Datei entspricht *]*.avi, ruft das Teil vor der Klammer ab, steckt es .aviwieder an und weist es als neuen Namen zu.

Um es direkt von Bash aus zu starten, verwenden Sie dieses semi-golfing Einzeiler:

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

Zitieren Sie mit freundlicher Genehmigung dieser Stack Overflow-Antwort .

(Getestet in Bash unter Ubuntu unter Windows. Es gibt wahrscheinlich eine viel kürzere Möglichkeit, dies mit PowerShell zu tun, aber ich wollte etwas zeigen, das für Leute verständlich ist, die keine regulären Ausdrücke kennen.)

Ben N
quelle
Rube Goldberg wäre stolz! Regexe sind eine echte PITA zum Lernen, aber sie sind es um ein Vielfaches wert - selbst auf der rudimentären Ebene, auf der ich sie anwenden kann.
Joe
1

Debian hat ein Paket mit dem Namen mmv, das möglicherweise auch in anderen Distributionen verfügbar ist und das leicht genug sein sollte, um es aus dem Quellcode zu kompilieren, wenn nicht. Damit können Sie Folgendes schreiben:

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

Weitere Informationen finden Sie in der Ubuntu-Manpage zu diesem Befehl.

MvG
quelle
0

Dadurch wird nach dem Muster gesucht und der Text mit sed ersetzt.

 $sed 's/\(.*]\)[a-zA-z0-9].*\(.avi\)/\1\2/' filename
Tejender Mohan
quelle