Ich habe einen Ordner mit mehreren hunderttausend Dateien mit dem Namen "ABC 123456". Ich muss zwischen den beiden Textblöcken einen Bindestrich hinzufügen, z. B. "ABC - 123456". Hinterlassen des Leerzeichens.
Automator bietet keine Methode zum Zählen von 4 Zeichen und zum Einfügen eines neuen Bindestrichs und Leerzeichens.
Ich habe diesen Terminalbefehl und habe daran herumgebastelt.
for file in *.txt
do
echo mv "$file" **"$file" count 3 "- "**
done
Kennt jemand ein Applescript oder kann mit dem Terminalbefehl helfen, der mir hilft, die Dateien umzubenennen?
Die Frage selbst ist auch nicht genau, denn das OP spricht über:
ABC 123456
(ohne Erweiterung), aber im Beispielcode mit *.txt
ErweiterungABC - 123456
, aber in der nächsten Aufnahme über counting to 4
und count 3
, zB nicht genau klar, was das Skript tun soll, zum Beispiel wenn find ABCD 12
orAB 345
Das Problem lässt sich in 3 separate Teile aufteilen:
Anzeige "Auswahl der richtigen Dateien". Die Auswahl der Dateien kann durch einige externe Dienstprogramme erfolgen, beispielsweise durch den find
Befehl. Die Hauptvorteile des find
sind:
man find
.)Anzeige "den neuen Namen vorbereiten". Dies kann durch externe Programme erfolgen, wie sed
oder awk
oder ein beliebiges Programm, das Text in Shell-Skripten manipulieren kann, oder es kann (in einigen einfachen Fällen wie diesem) mit sich selbst erfolgen bash
- und es ist möglich, eine teure Befehlsausführung zu sparen. (Für Hunderttausende von Dateien macht es einen Unterschied).
Die folgende:
${file/ /-}
ersetzt (ersetzt) ein Leerzeichen (den / /
Teil) durch den Bindestrich ( /-
). Schreiben ist also möglich
mv "$file" "${file/ /-}"
und speichern Sie die sed
Ausführung.
Eine der alternativen Lösungen könnte also beispielsweise die folgende sein:
#!/bin/bash
while IFS= read -r -d $'\0' filename
do
newfilename="${filename/ /-}"
[[ "$filename" != "$newfilename" ]] && echo mv -i "$filename" "$newfilename"
done < <(find . -maxdepth 1 -type f -iname "* *.jpg" -print0)
Das Obige ist für den DRY RUN - es zeigt nur, was getan wird, für die eigentliche Ausführung entfernen Sie die echo
.
Zersetzung:
Auswahl der richtigen Dateien für die Umbenennung: die find . -maxdepth 1 -type f -iname "* *.jpg" -print0
werden alle finden
-maxdepth 1
)-type f
)-print0
)der Kreislaufwhile IFS= read -r -d $'\0' filename; do ... done < <( )
find
Befehls-d $'\0'
)-r
) /Fortgeschrittenes Thema - muss hier nicht erklärt werden/IFS=
Trimmen von führenden und nachgestellten Leerzeichen aus dem Dateinamen (auch ein etwas fortgeschrittenes Thema)Vorbereiten des neuen Dateinamensnewfilename="${filename/ /-}"
bash
intern (ohne Ausführung eines externen Befehls).${filename/ /- }
die eigentliche Umbenennung erfolgt durch den mv
Befehl (siehe man mv
vom Terminal), wo
-i
What fragt den Benutzer, ob es hier bereits eine Datei mit dem neuen Dateinamen gibt (nicht überschreiben)und die mv
wird nur ausgeführt, wenn die newfilename
von der verschieden istfilename
[[ "$filename" != "$newfilename" ]]
Die obige Lösung ist größtenteils fehleranfällig, aber immer noch nicht sehr effektiv, da für Hunderttausende Dateien der Befehl Hunderttausendmal ausgeführt wird mv
. mv
Die Lösung kann sein: Verwenden Sie ein Dienstprogramm, das die Dateinamen lesen und die Umbenennung durchführen kann, ohne den Befehl N-mal auszuführen . Zum Beispiel das „große Geschütz“ der Systemadministratoren das „Perl“, als:
find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
perl -0nle '$n=$_; $n=~s/ /-/; rename $_,$n unless($_ eq $n || -e $n)'
was alle Dateien umbenennt was das find
in einer Ausführung ausgibt - zB viel schneller als Tausende von mv
Ausführungen.
Tor-Tests (DRY RUN) verwenden Folgendes:
find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
perl -0nle '$n=$_; $n=~s/ /-/; print qq{old:$_ new:$n\n} unless($_ eq $n || -e $n)' #print instead of the rename
Ps: das Perl ist mächtig genug, um alles selbst zu handhaben, zB. der Find-Befehl auch, aber es ist ein fortgeschritteneres Thema ...
Ps2: Mein Englisch ist viel schlechter als mein bash
, also könnte jemand freundlicherweise diesen Beitrag bearbeiten, um Dinge hinzuzufügen / zu korrigieren.. ;)
Wenn Ihre Dateinamen "ABC 123456" mit einem einzelnen Leerzeichen zwischen den ersten 3 und den folgenden sind, versuchen Sie, das Leerzeichen durch ein Zeichen (oder einen Bindestrich oder so) zu ersetzen, damit es wie ABC-123456 aussieht.
Ich habe diesen Artikel gefunden , der erklärt, wie das geht.
Beispiel:
Beachten Sie, dass der folgende Befehl nur Leerzeichen durch Bindestriche ersetzt. Wenn Sie eine andere Ersetzung benötigen, müssen Sie den Befehl entsprechend ändern
for i in *.JPG; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done
Andere:
Wenn Sie anstelle eines Bindestrichs Unterstriche oder andere Zeichen verwenden möchten, ändern Sie einfach den s, ,-,g
Teil des obigen Befehls in s, ,_,g
.
Wie Sie diesen Artikel sehen können .
Hier ist ein Test auf meinem MBA 10.9.5 (ich habe eine ABC 123456.png-Datei verwendet) und in einem neuen Ordner abgelegt. Dann habe ich die CD in dieses Verzeichnis im Terminal verschoben und ausgeführt
for i in *.png; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done
Ergebnis ist, es funktioniert großartig (es benennt die Datei um)
Wie funktioniert es: Es würde das Leerzeichen im Dateinamen aller *.png-Dateien in diesem Ordner ersetzen, stellen Sie also sicher, dass Sie es zuerst im richtigen Ordner haben.