Befehl mit Perl-Ausdruck umbenennen

8

Ich kann den folgenden Befehl erfolgreich verwenden und bin mit diesem Befehl ziemlich sicher, andere Kombinationen zu erstellen:

rename 's/\.htm/\.html/' *.htm

Ich möchte jedoch mehr darüber wissen, insbesondere darüber s. Sie sagen, es sei ein Perl-Ausdruck. Ich habe keine Perl-Programmiersprache gelernt, daher habe ich keine Ahnung, warum es so ein 's/\.htm/\.html/'Argument gibt. Würdest du mir sagen, was es ist? Danke fürs Lesen.

Lächeln
quelle
fyi: Ich verwende [Code unregelmäßig in] Perl, aber betrachte es nicht als Perl-Ausdruck. Wenn Sie ein ':' vor das s setzen, wäre dies ein vi [line] -Befehl, den ich in den 80ern gelernt habe, bevor Perl veröffentlicht wurde. Das Konstrukt existiert in vielen * nix-Tools
guiverc
Wenn Sie mehr darüber erfahren möchten, suchen Sie möglicherweise nach "regulären Ausdrücken" (falls interessiert). Das Konstrukt ist auch in sed (Stream-Bearbeitung) und (
jede Menge

Antworten:

9

Im Allgemeinen werden renamedie Dateinamen gemäß der als erstes Argument des Befehls angegebenen Regel umbenannt. Die Dateinamen werden von den Argumenten geliefert, die auf das erste folgen.

Das erste Argument im Beispielbefehl ( rename 's/\.htm/\.html/' *.htm) enthält Pelzteile, wobei in diesem Fall /ein Trennzeichen für diese Teile ist:

s/regexp/replacement/[flags]
  1. Der sBefehl bedeutet Ersatz : s/<old>/<new>/. Passen Sie den regulären Ausdruck an den Inhalt des Musterbereichs an. Wenn gefunden, ersetzen Sie die übereinstimmende Zeichenfolge durch Ersetzen.

  2. Regulärer Ausdruck, der mit den Zeichenfolgen übereinstimmt, die ersetzt werden sollen. Im aktuellen Fall ist dies nur die Zeichenfolge .htm.

    In den meisten regulären Ausdrücken .stimmt der Punkt mit jedem Zeichen überein. In diesem Fall möchten wir den Punkt wörtlich verwenden, daher müssen wir seiner speziellen Bedeutung durch Verwendung des Schrägstrichs \(unter Angabe eines einzelnen Zeichens) entgehen .

  3. Ersatz des Stichs / Regexp auf 2 abgestimmt.

  4. Flag, das im aktuellen Beispiel nicht dargestellt wird. Es könnte zum Beispiel das Flag sein g- wenden Sie den Ersatz auf alle Übereinstimmungen auf den regulären Ausdruck an, nicht nur auf den ersten. Nehmen wir an, wir haben eine Datei mit dem Namen my.htm-file.htm:

    • Der ursprüngliche Befehl rename 's/\.htm/\.html/' *.htmbenennt die Datei folgendermaßen um : . Schauen Sie sich am Ende der Antwort an, wie Sie dieses Problem vermeiden können.my.html-file.htm

    • Durch Hinzufügen des gFlags - rename 's/\.htm/\.html/g' *.htm- lautet der neue Dateiname : .my.html-file.html

Entsprechend den Dateinamen: *kann eine beliebige Anzahl von Zeichen darstellen (einschließlich null, dh null oder mehr Zeichen). Die Shell erweitert diesen Glob und übergibt die übereinstimmenden Dateinamen als separate Argumente an renameSo *.htm- stimmt mit allen Dateinamen im aktuellen Pfad überein, die mit der Zeichenfolge enden .htm. Wenn Sie zum Beispiel haben 1.htm, 2.htm, 3.htm, 4.htm, und 5.htmdann rename 's/\.htm/\.html/' *.htmpassiert genau die gleichen Argumente wie ausgeführt umbenennen:

rename 's/\.htm/\.html/' 1.htm 2.htm 3.htm 4.htm 5.htm

Der gesamte Befehl ( rename 's/\.htm/\.html/' *.htm) könnte folgendermaßen gelesen werden:

rename `<substitute>/<the string ".htm">/<with the string ".html">/` <do it for all files in the current path that end with ".htm">

Kehren wir zum Beispiel zurück, wenn wir eine Datei mit dem Namen haben my.htm-file.htm. Wahrscheinlich möchten wir den letzten Teil des Dateinamens, die sogenannte Erweiterung, nach dem letzten Punkt ändern. Zu diesem Zweck sollten wir den renameBefehl folgendermaßen ändern :

rename 's/\.htm$/\.html/' *.htm

Wo das $Zeichen mit dem Ende der Zeile übereinstimmt und wörtlich "rückwärts lesen" bedeutet.

^- Entspricht der Nullzeichenfolge am Anfang des Musterraums, dh was nach dem Zirkumflex erscheint, muss am Anfang des Musterraums erscheinen. ( lesen Sie mehr )

^fungiert nur am Anfang des regulären Ausdrucks oder Unterausdrucks (dh nach \(oder \|) als Sonderzeichen . Tragbare Skripte sollten jedoch ^zu Beginn eines Unterausdrucks vermieden werden, da POSIX Implementierungen zulässt, die ^in diesem Kontext als normales Zeichen behandelt werden .

$- Es ist dasselbe wie ^, bezieht sich jedoch auf das Ende des Musterraums. $fungiert auch nur am Ende des regulären Ausdrucks oder Unterausdrucks (dh vor \)oder \|) als Sonderzeichen , und seine Verwendung am Ende eines Unterausdrucks ist nicht portierbar.


Verweise:

pa4080
quelle
1
s als Ersatz. In Ordung. Danke für deine Antwort. Viele Menschen werden von Ihrer Antwort profitieren. Ich wünsche Ihnen einen schönen Tag :)
Smile
2
"Das zweite Argument, das ist der Dateinamen-Übereinstimmungsausdruck." Nein, renamesieht nie *.htm. Bevor es ausgeführt wird rename, erweitert die Shell diesen Glob und übergibt die übereinstimmenden Dateinamen als separate Argumente an rename. Wenn Sie 1.htm, 2.htm, 3.htm, 4.htm, und 5.htmdann rename 's/\.htm/\.html/' *.htmpassiert genau die gleichen Argumente renamewie ausgeführt rename 's/\.htm/\.html/' 1.htm 2.htm 3.htm 4.htm 5.htm. Sind Sie bereit, diese zu bearbeiten oder zu akzeptieren, um dies zu korrigieren? Diese Antwort ist ansonsten gut.
Eliah Kagan
2
@EliahKagan: Danke für diesen Hinweis! Ich habe eine Bearbeitung vorgenommen.
pa4080