webentwicklung-frage-antwort-db.com.de

Benennen Sie Dateien mit regulären Ausdrücken unter Linux um

Ich habe eine Reihe von Dateien mit dem Namen:

Friends - 6x03 - Tow Ross' Denial.srt
Friends - 6x20 - Tow Mac and C.H.E.E.S.E..srt
Friends - 6x05 - Tow Joey's Porshe.srt

und ich möchte sie wie folgt umbenennen

S06E03.srt
S06E20.srt
S06E05.srt

was soll ich tun, um die Arbeit im Linux-Terminal zu erledigen? Ich habe umbenennen installiert, aber Sie erhalten Fehler mit den folgenden:

rename -n 's/(\w+) - (\d{1})x(\d{2})*$/S0$2E$3\.srt/' *.srt
39
orezvani

Sie haben einen Punkt vor dem Sternchen vergessen:

rename -n 's/(\w+) - (\d{1})x(\d{2}).*$/S0$2E$3\.srt/' *.srt

Unter OpenSUSE, RedHat und Gentoo müssen Sie die Perl-Version von rename verwenden. Diese Antwort zeigt, wie man es erhält. In Arch heißt das Paket Perl-rename.

56
Thor

Wirklich coole Lil Diddy. finde + Perl + xargs + mv

xargs -n2 ermöglicht das Drucken von zwei Argumenten pro Zeile. In Kombination mit Perls print $_ (um zuerst $ STDIN zu drucken), ist dies ein leistungsstarkes Umbenennungswerkzeug.

find . -type f | Perl -pe 'print $_; s/input/output/' | xargs -n2 mv

Ergebnisse von Perl -pe 'print $_; s/OldName/NewName/' | xargs -n2 am Ende wird:

OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext

Auf meinem System war Perls rename nicht verfügbar.


Wie funktioniert es?

  1. find . -type f gibt Dateipfade aus (oder Dateinamen ... Sie steuern hier, was von Regex verarbeitet wird!)
  2. -p druckt Dateipfade, die von Regex verarbeitet wurden, -e führt ein Inline-Skript aus
  3. print $_ druckt zuerst den ursprünglichen Dateinamen (unabhängig von -p)
  4. -n2 druckt zwei Elemente pro Zeile
  5. mv ruft die Eingabe der vorherigen Zeile ab
8
Jonathan Komar

Bearbeiten: Besseres Auflisten der Dateien ohne Verwendung von IFS und ls, während noch sh kompatibel sind.

Ich würde ein Shell-Skript dafür machen:

#!/bin/sh
for file in *.srt; do
  if [ -e "$file" ]; then
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
    mv "$file" "$newname"
  fi
done

Vorheriges Drehbuch:

#!/bin/sh
IFS='
'
for file in `ls -1 *.srt`; do
  newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
  mv "$file" "$newname"
done
8
Creak

Nicht jede Distribution enthält ein rename -Dienstprogramm, das reguläre Ausdrücke wie in den obigen Beispielen unterstützt - unter anderem RedHat, Gentoo und ihre Derivate.

Alternativen zu versuchen, zu verwenden, sind Perl-rename und mmv.

7
gerrit_hoekstra

Verwenden Sie mmv (Massenbewegung?)

Es ist einfach, aber nützlich: Es verwendet * Für eine beliebige Zeichenfolge und ? Für ein beliebiges Zeichen in der Übereinstimmungszeichenfolge und #X In der Ersetzungszeichenfolge, um auf die X-te Übereinstimmung zu verweisen.

In deinem Fall:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt'

Hier stellen #1#2 Die zwei Ziffern dar, die von ?? Erfasst werden (Match # 1 und # 2).
Also wird folgender Ersatz gemacht:

Friends - 6x?? - Tow *           .srt    matches
Friends - 6x03 - Tow Ross' Denial.srt    which is replaced by
            ↓↓
        S06E03.srt

mmv bietet auch Übereinstimmungen mit [ und ] und ; an.

Sie können nicht nur umbenennen , sondern auch verschieben, kopieren, anhängen und Link Dateien.

Lesen Sie die oben verlinkte Manpage für mehr!

Persönlich verwende ich es zum Auffüllen von Zahlen, sodass nummerierte Dateien in der gewünschten Reihenfolge angezeigt werden, wenn sie lexikografisch sortiert werden: file_?.extfile_0#1.ext

5
xoxox

wenn dein linux nicht anbietet umzubenennen , könntest du auch folgendes benutzen:

find . -type f -name "Friends*" -execdir bash -c 'mv "$1" "${1/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt}"' _ {} \;

ich benutze dieses Snippet ziemlich oft, um Ersetzungen mit Regex in meiner Konsole durchzuführen.

ich bin nicht sehr gut in Shell-Sachen, aber soweit ich diesen Code verstehe, würde seine Erklärung wie folgt lauten: Die Suchergebnisse Ihres finden werden an einen bash-Befehl ( bash -c ) weitergeleitet werden, in dem Ihr Suchergebnis innerhalb von $ 1 als Quelldatei. das folgende Ziel ist das Ergebnis einer Substitution innerhalb einer Subshell, wobei der Inhalt von $ 1 (hier: just 1 innerhalb Ihrer Parameter-Substitution {1 // find/replace} ) wird Seien Sie auch Ihr Suchergebnis. das {} leitet es an den Inhalt von - execdir weiter

bessere Erklärungen wären sehr dankbar :)

bitte beachten Sie: Ich habe nur Ihren regulären Ausdruck kopiert. Bitte testen Sie es zuerst mit Beispieldateien. Je nach System müssen Sie\d und\w möglicherweise in Zeichenklassen wie [[: digit:]] oder [[: alpha:]] ändern.\1 sollte jedoch für die Gruppen funktionieren.

1
meistermuh

Sie können rnm verwenden:

rnm -rs '/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt/' *.srt

Erläuterung:

  1. -rs: Ersetze einen String der Form /search_regex/replace_part/modifier
  2. (\d) und (\d+) im (\d)x(\d+) sind zwei erfasste Gruppen (\1 und \2 beziehungsweise).

Weitere Beispiele hier .

0
Jahid