Wie benenne ich mehrere Dateien um, indem ich die Zeichenfolge im Dateinamen ersetze? Diese Zeichenfolge enthält ein "#"


42

https://serverfault.com/questions/70939/how-to-replace-a-text-string-in-multiple-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multiple-files-by-replacing-word-in-file-name

https://serverfault.com/questions/212153/replace-string-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-string-in-linux

Diese genannten Artikel haben alle meine Frage beantwortet. Jedoch arbeitet keiner von ihnen für mich. Ich vermute, es liegt daran, dass die Zeichenfolge, die ich ersetzen möchte, ein # enthält. Gibt es eine spezielle Möglichkeit, dies zu beheben?

Ich habe eine Image-Datei, bei der während einer Site-Migration ein é durch # U00a9 ersetzt wurde. Diese sehen so aus:

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

und ich möchte es in so etwas ändern:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

AKTUALISIEREN:

Diese Beispiele beginnen alle mit "LU00a9ucky", aber hier sind viele Bilder mit unterschiedlichen Namen. Ich ziele einfach auf den "# U00a9" -Teil der Zeichenfolge ab, um ihn durch "safe" zu ersetzen.


3
Also, was hast du eigentlich versucht? Ich sehe, dass Sie auf ein paar Fragen verwiesen haben und sagen, dass sie gescheitert sind, aber wie sind sie gescheitert? IMO das beste Beispiel verwendet den renameBefehl. Ich vermute, Ihre Umbenennung wäre so einfach wie rename -n 's/#/safeNBC/' *.jpg.
Zoredache

Ich habe es versucht rename -n 's/#U00a9/safe/' *.jpgund der Befehl wurde akzeptiert, aber es sind keine Änderungen aufgetreten.

Sicher, wie Sie aus der Dokumentation gesehen haben, die Sie sicherlich überprüft haben, -nist die no actOption. So können Sie sehen, ob es funktioniert, bevor Sie es tatsächlich verwenden. Wurden in der Ausgabe auf dem Bildschirm die potenziellen neuen Namen korrekt angezeigt?
Zoredache

Ich entschuldige mich, dass ich Ihr Beispiel kopiert und eingefügt habe, ohne vollständig darauf zu achten. Ich habe den Befehl zum Umbenennen ohne das -n ausgeführt. Ich glaube, @ DTK adressiert das Problem, ich bin der # nicht entgangen.

Ersetzen von Zeichenfolgen in Dateinamen unter MacOS: superuser.com/questions/152627/…
Anton Tarasenko

Antworten:


64

Zum Ersetzen #von somethingelseDateinamen im aktuellen Verzeichnis (nicht rekursiv) können Sie das GNU- Dienstprogramm zum Umbenennen verwenden :

rename  's/#/somethingelse/' *

Zeichen wie -müssen mit einem Escapezeichen versehen werden \.

Für Ihren Fall möchten Sie verwenden

rename 's/#U00a9/safe/g' *

Beachten Sie, dass Sie, wenn Sie nur eine bestimmte Auswahl von Dateien bearbeiten möchten, z. B. nur *.jpg, die endgültige Eingabe so anpassen, dass sie dieser Auswahl entspricht:

rename 's/#U00a9/safe/g' *.jpg

Verwenden Sie das -nFlag, um einen Test durchzuführen, bevor Sie die Dateinamen tatsächlich ändern :

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

Für OS X können GNU Umbenennungs installiert werden Homebrew : brew install rename.


Dies funktionierte nicht auf meinem Computer (Arch Linux), aber Miks Antwort tat es.
Marcvangend

@marcvangend Welche Version von verwendest renamedu? # sudo pacman -S perl-renamewird die Perl-Version installieren, die leistungsfähiger ist und möglicherweise ausreicht, um diese Antwort für Sie arbeiten zu lassen.
John Gowers

@ JohnGowers Danke! Mir war nicht klar, dass es zwei Versionen gibt. Auf meinem System rename --versionkehrt rename from util-linux 2.29.2ja das ja nicht die Perl-Version zurück.
Marcvangend

5
Es gibt zwei gängige renameHilfsprogramme, aber keines davon wird von GNU entwickelt: Debian-basierte Distributionen enthalten ein renameHilfsprogramm mit ihrem Perl-Paket, während Red Hat-basierte Distributionen das renameHilfsprogramm util-linuxaus der Linux-Kernel-Organisation verwenden. Ihr Link ist zur renameC- Funktion aus der GNU-Standardbibliothek.
Anthony G - Gerechtigkeit für Monica

2
In dieser Antwort, warum haben wir zu schreiben /ginrename 's/#U00a9/safe/g' *
Nikhil

21

Suchen Sie die Liste der Dateien und ersetzen Sie das Schlüsselwort. Unten ist ein Beispiel

find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;

1
Sie müssen Ihre mvArgumente in Anführungszeichen setzen , falls der Name Leerzeichen enthält
Stop Harming Monica

Ich musste alle Dateien * _spec.rb bis * _controller_spec.rb ersetzen und Ihre Lösung funktionierte für mich. Vielen Dank.
Jedi

18

Dies ist nicht schwer, stellen Sie einfach sicher, dass der Oktothorpe (#) im Namen durch einen umgekehrten Schrägstrich (\) vorangestellt wird.

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 

Ihre Erklärung macht Sinn, den #Klängen zu entkommen, die ich brauche. Ich sehe keinen Backslash in Ihrem Beispiel. Sollte es so aussehen: s/\#U00a9/safe/

@LeonFrancisShelhamer guten Fang. Es verschluckte den Backslash. Ich werde modifizieren.

17

#Verwenden Sie zum Verlassen der Shell einfache Anführungszeichen ( '#'), doppelte Anführungszeichen ( "#") oder umgekehrte Schrägstriche ( \#).

In Ihrem Fall ist es am einfachsten, den renameBefehl zu verwenden (falls verfügbar):

rename '#U00a9' safe *.jpg

2
Vielen Dank. Während die Antwort mit der höchsten Bewertung ( rename 's/#/somethingelse/' *) auf meinem Computer (Arch Linux) nicht funktionierte, war dies der Fall.
Marcvangend

1
Dies funktioniert mit dem Umbenennungsbefehl von util-linux.
17.

10

Ich weiß nicht, wie ich es anstellen soll, aber Sie können dies in einer Bash-Shell versuchen:

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

Erläuterung:

  1. durchläuft alle Dateinamen, die mit dem Glob übereinstimmen (Lucky- # U00a9NBC - *. jpg)
  2. Benennt die Datei mit dem Befehl move (mv) um
  3. verwendet die native Bash-Parameter-Ersetzung $ {var / Pattern / Replacement}, um den neuen Namen zu erstellen ("$ {f / # U00a9 / safe}")

Weitere Informationen zur Parametersubstitution (bei der es sich um eine stark ungenutzte IMO handelt): http://www.tldp.org/LDP/abs/html/parameter-substitution.html


Obwohl dieser Code die Frage beantworten kann, ist er für sich genommen nicht sehr nützlich. Wenn Sie erläutern, wie das Problem gelöst werden kann, verbessern Sie den Nutzen und den langfristigen Wert der Antwort.
Anthony G - Gerechtigkeit für Monica

Erklärungen und weitere Lektüre gemäß Anthonys Kommentar hinzugefügt.
Gregory Patmore

1

Die obigen Beispiele funktionierten auf meinem System nicht (CentOS 5.6), daher habe ich einen (möglicherweise systemspezifischeren) Befehl gefunden, der funktioniert (Hinweis: Es muss ein '#' mit \in der Befehlszeile eingegeben werden):

rename \#U00a9 safe *.jpg

[Außerdem: Ich habe noch nicht genug Reputation, um einen Kommentar abzugeben, also als Antwort auf Nikhils Frage bezüglich der Verwendung von /gin rename 's/old_string/new_string/g'(in den Kommentaren für eine andere Antwort oben gestellt):

Verwenden Sie den gModifikator, um eine 'globale' Ersetzung durchzuführen (d. H., Um old_string durch new_string zu ersetzen, so oft old_string vorkommt). Dies sollte in meiner Antwort nicht notwendig sein, da das renameauf alle mit angegebenen Dateien angewendet wird *. Eine kurze Erklärung dieses und anderer Modifikatoren finden Sie unter https://www.computerhope.com/unix/rename.htm .]


Richtig; Von Fedora abgeleitete Betriebssysteme wie CentOS haben eine andere Version renameals von Debian abgeleitete Betriebssysteme. Siehe unix.stackexchange.com/a/238862/135943 . Übrigens ist CentOS 5.6 ziemlich alt und ich empfehle Ihnen, ein Upgrade durchzuführen.
Wildcard

Ah, danke für die Erklärung + Link. Das veraltete Betriebssystem ist in Arbeit und es liegt nicht an mir, ein Upgrade durchzuführen :), aber es wird ein neuer Cluster erstellt und vermutlich werden wir ein Upgrade durchführen, wenn wir umziehen ...
Ezra Citron

0

Hier ist die DTK-Lösung, die in wiederverwendbare Bash-Funktion eingebettet ist:

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

So können Sie es verwenden:

renameFilesRecursively /home/user/my-files apple orange

0

Hat eigentlich renameeine Option genau dafür genannt --substoder -skurz gesagt. Die Regex-Syntax muss nicht verwendet werden.

rename -s '#U00a9' 'safe' *

Wenn Sie mehrere Vorkommen ersetzen möchten, verwenden Sie --subst-alloder -S.

Übrigens wollte ich nur eine Zeichenkette durch nichts ersetzen (sie aus dem Dateinamen entfernen) ... nun, wir haben auch eine Option dafür -d/--deleteund -D/--delete-all:

rename -d '#U00a9' *

-1

Eine weitere Option ist die Verwendung pyRenamereiner Anwendung, die speziell für die Stapelumbenennung entwickelt wurde.

Es kann mit installiert werden sudo apt-get install pyrenamer

Einzelheiten zur Verwendung finden Sie in der README-Datei auf GitHub .


1
Wenn Sie wirklich der Meinung sind, dass dies die Frage beantworten könnte, fügen Sie Ihrer Antwort eine Erklärung hinzu. An sich installiert es nur ein Paket. Sie sollten erklären, was der Befehl bewirkt, und ein Beispiel bereitstellen, das die spezifischen Anforderungen des OP behandelt.
Roaima
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.