Wie kann ich Dateien in einem macOS-Terminal stapelweise umbenennen?

123

Ich habe einen Ordner mit einer Reihe von Dateien mit dem Namen:

prefix_1234_567.png
prefix_abcd_efg.png

Ich möchte einen Unterstrich und den mittleren Inhalt stapelweise entfernen, damit die Ausgabe wie folgt lautet :

prefix_567.png
prefix_efg.png

Relevant, aber nicht vollständig erklärend:

Kidnim
quelle
Schauen Sie sich den Bereich und die Teilstring-Methoden von NSString und NSMutableString an
Grady Player
1
Haben Sie über nicht-terminale Lösungen nachgedacht? Ein Automator-Workflow kann diese Art von Vorgängen problemlos ausführen. Sie können einen Automator-Workflow erstellen, um alle Dateien umzubenennen und den Text _*_durch ein Leerzeichen zu ersetzen .
Encryptic
Ich dachte, Automator könnte keine Wildcards machen
Kidnim

Antworten:

234

In Ihrem speziellen Fall können Sie den folgenden bashBefehl verwenden ( bashist die Standard-Shell unter macOS):

for f in *.png; do echo mv "$f" "${f/_*_/_}"; done

Hinweis: Wenn die Möglichkeit besteht, dass Ihre Dateinamen beginnen -, platzieren Sie sie -- vor ihnen [1]:
mv -- "$f" "${f/_*_/_}"

Hinweis: echoWird vorangestellt mv, um einen Trockenlauf durchzuführen. Entfernen Sie es, um das eigentliche Umbenennen durchzuführen.

Sie können es über die Befehlszeile ausführen oder in einem Skript verwenden.

  • "${f/_*_/_}"ist eine Anwendung der bash Parametererweiterung : Das (erste) Teilstring-Übereinstimmungsmuster _*_wird durch ein Literal ersetzt _, wodurch das mittlere Token effektiv aus dem Namen herausgeschnitten wird.
  • Beachten Sie, dass dies _*_ein Muster ist (ein Platzhalterausdruck, wie er auch zum Globbing verwendet wird), kein regulärer Ausdruck (um mehr über Muster zu erfahren, auszuführen man bashund zu suchen Pattern Matching).

Wenn Sie häufig Dateien im Batch umbenennen, sollten Sie ein spezielles Tool wie das Perl-basierte renameDienstprogramm installieren . Unter macOS können Sie es mit dem beliebten Paketmanager Homebrew wie folgt installieren :

brew install rename

Hier ist das Äquivalent des Befehls oben mit rename:

rename -n -e 's/_.*_/_/'  *.png

Wieder führt dieser Befehl einen Trockenlauf durch; entfernen -n, um das eigentliche Umbenennen durchzuführen.

  • Führt ähnlich wie die bashLösung s/.../.../eine Textersetzung durch, es werden jedoch - anders als in bash- echte reguläre Ausdrücke verwendet.

[1] Der Zweck eines speziellen Arguments --, das von den meisten Dienstprogrammen unterstützt wird, besteht darin, zu signalisieren, dass nachfolgende Argumente als Operanden (Werte) behandelt werden sollten , auch wenn sie von Anfang an wie Optionen aussehen , wie Jacob C. bemerkt.-

mklement0
quelle
3
tolle Antwort, hat perfekt funktioniert. Ich schätze auch, dass Sie zurückgegangen sind und es bearbeitet haben, um es genauer zu erklären und eine elegantere Lösung zu bieten, wenn ich dies wiederhole.
Nochmals
4
Ein Beispiel mit übereinstimmenden Ersetzungen ( .*-> $1), z. B. Umbenennen Foo bar S01E01 biz baz.extin S01E01.ext:rename -n -e 's/.*(S[0-9]{2}E[0-9]{2}).*(\.[a-z]{2,4})/$1$2/' *
Steve Robbins
2
Ich liebe die Idee, sie echofür Trockenläufe zu verwenden. Danke für den Tipp!
James Wright
Sehr zu empfehlen, nur diebrew install rename
Chris Redford
98

Um Dateien umzubenennen, können Sie das renameDienstprogramm verwenden:

brew install rename

So ändern Sie beispielsweise eine Suchzeichenfolge in allen Dateinamen im aktuellen Verzeichnis:

rename -nvs searchword replaceword *

Entfernen Sie den Parameter 'n', um die Änderungen zu übernehmen.

Mehr Info: man rename

David Thomas
quelle
1
OS XVersionen von GNU bash( x86_64-apple-darwin ) enthalten das Dienstprogramm zum Umbenennen nicht.
l'L'l
4
Danke, ja, es muss installiert werden überbrew install rename
David Thomas
2
Dieser Tipp ist super! Ich habe getippt rename -vs GLYCOPHORIN GLYCC *und jetzt werden automatisch mehr als 450 Dateien umbenannt. Und super schnell auch.
Sander W. van der Laan
3
Ausgezeichnet! Ich liebe den Teil "Zeigen, was geändert werden würde", BEVOR er die Dinge tatsächlich umbenennt!
Ben Duffin
3
Sie können auch einen regulären Ausdruck verwenden. benenne 's / 123 / onetwothree / g' * um
Bryan
12

Sie könnten sed verwenden:

ls * | sed -e 'p;s@_.*_@_@g' | xargs -n2 mv

Ergebnis:

prefix_567.png prefix_efg.png

* Um zuerst einen Trockenlauf durchzuführen, ersetzen Sie ihn mvam Ende durchecho

Erläuterung:

  • e: optional für nur 1 sed Befehl.
  • p: Um die Eingabe in sed zu drucken, ist dies in diesem Fall der ursprüngliche Dateiname vor jeder Umbenennung
  • @: ist ein Ersatz für / Zeichen, um sed besser lesbar zu machen. Das heißt, anstatt sed s / search / replace / g zu verwenden, verwenden Sie s @ search @ replace @ g
  • _. *: Der Unterstrich ist ein Escapezeichen, das sich auf das tatsächliche '.' bezieht. Zeichen null oder mehrmals (im Gegensatz zu JEDEM Zeichen in Regex)
  • -n2: Gibt an, dass 2 Ausgänge als Parameter an mv übergeben werden müssen. Für jede Eingabe von ls generiert dieser sed-Befehl 2 Ausgaben, die dann an mv geliefert werden.
l'L'l
quelle
1
Clevere, wenn auch etwas arkane Lösung. Wenn Sie dies allgemeiner gestalten, um auch Dateinamen mit eingebetteten Leerzeichen zu unterstützen, wird dies noch geheimnisvoller: ls * | xargs -I % bash -c 'echo mv "%" "$(sed 's@_.*_@_@' <<<"%")"'(Entfernen echo, um es tatsächlich umzubenennen).
mklement0
2
Arkan? Ich liebe es!
Bilal Akil
7

Ich hatte eine Reihe von Dateien, die so aussahen: be90-01.png und musste den Bindestrich in Unterstrich ändern. Ich habe das benutzt, was gut funktioniert hat:

for f in *; do mv "$f" "`echo $f | tr '-' '_'`"; done
JanB
quelle
2

Sie können den renameBefehl mithilfe von installieren brew. mach brew install renamees einfach und benutze es.

Nisim Joseph
quelle
1

Verwenden von mmv

mmv '*_*_*' '#1_#3' *.png
αғsнιη
quelle
Sie müssen zuerst installieren sudo apt-get install mmv.
αғsнιη
1
Da dies OS X war, ist das korrekte Installationsverfahren brew install mmv.
Buckaroo1177125
1

Versuche dies

for i in *.png ; do mv "$i" "${i/remove_me*.png/.png}" ; done

Hier ist ein anderer Weg:

for file in Name*.png; do mv "$file" "01_$file"; done
Joolah
quelle