Erstellen Sie in Automator einen Konvertierungsdienst für die Textkodierung

Ich habe versucht, einen Finder-Dienst zu erstellen, um die Textcodierung einiger Dateien einfach zu konvertieren. Weil der Standardzeichensatz für vereinfachtes Chinesisch in Windows der chinesische nationale Standard GB18030 ist (nicht das auf dem Mac verwendete UTF-8).

Mit etwas Hilfe von den Antworten bei services - Automator Get Filename of Selected File - Ask Different habe ich eingerichtet, dass der Service selected: Files or folders in: Finder empfängt

Dann habe ich dieses Shell-Skript in Automator erstellt:

for f in "$@"
do
    iconv -f gb18030 -t utf-8 f > f.new
done

Wenn ich jedoch den Dienst bei der Auswahl von ausführe , sehe ich die neu erstellte im Finder fnicht . f.newIch glaube, ich habe den Ausgabepfad falsch eingestellt. Aber ich weiß nicht, was der richtige Weg ist, um es zu beheben.

Automator-Screenshot

Damit es funktioniert, sollte die Pass-Eingabe: in der Prozedur als Argumente anstelle von stdin verwendet werden .
Ich habe meine Antwort geändert, um einen Kommentar von Gordon Davisson anzusprechen, und schlage vor, dass Sie stattdessen die geänderte Antwort verwenden.

Antworten (1)

Ändern:

for f in "$@"
do
    iconv -f gb18030 -t utf-8 f > f.new
done

Zu:

for f in "$@"; do
    if [[ ! $(basename "$f") =~ .*\..* ]]; then
        iconv -f gb18030 -t utf-8 < "$f" > "${f}-new"
    else
        iconv -f gb18030 -t utf-8 < "$f" > "${f%.*}-new.${f##*.}"
    fi
done

Und legen Sie Pass input: to als Argumente für die Aktion Shell-Skript ausführen fest .


Um den Kommentar von Gordon Davisson zur Behandlung eines Dateinamens ohne Erweiterung zu adressieren , habe ich den Code in meiner obigen Antwort geändert.

Der Code testet den Dateinamenteil des vollständig qualifizierten Pfadnamens, der an die Aktion „Run Sell Script“ übergeben wird , mithilfe einer Regex , um zu sehen, ob er eine Erweiterung oder genauer gesagt ein als Teil des Dateinamens hat, und wenn der Dateiname kein enthält, verarbeitet er die if-Zweig , andernfalls verarbeitet er den else-Zweig ...

Beachten Sie auch, dass die Verwendung eines Globs anstelle eines Regex , z. B.:

if [[ ! $(base name "$f") == *.* ]]; then

Würde auch funktionieren, um eine Erweiterung zu testen. In jedem Fall folgt der neue vollständig qualifizierte Pfadname einem dieser beiden Beispiele:

  • /path/to/filenamewird:/path/to/filename-new
  • /path/to/filename.extwird:/path/to/filename-new.ext

Hinweis: Diese Antwort geht davon aus, dass vollständig qualifizierte Pfadnamen keine Nullzeichen und/oder Wagenrückläufe und/oder Zeilenvorschübe enthalten. IMO richtige Pfadnamen enthalten solche Zeichen nicht und ich werde sie nicht testen.

@jackxujh, ich habe meine Antwort aktualisiert. Anscheinend müssen Sie die Eingabedatei in den Befehl leiten und dann die Ausgabe in die neue Datei umleiten. Die alte und die neue Datei sollten sich jetzt am selben Ort befinden. Sowie das, was Sie in Ihrem Kommentar zu Ihrer Frage angemerkt haben.
Nachdem ich die Einstellung der Pass-Parameter< geändert hatte, begann die vorherige Bearbeitung der Antwort (ohne ) einwandfrei zu funktionieren. Und dann sah ich, dass du das <Zeichen hinzugefügt hast. Und es funktioniert auch!
Jetzt macht der Dienst zwar file.txt.newmit konvertierter Textcodierung lauffähig, file-new.txtwäre aber im Idealfall noch besser. Ist das auch möglich? Danke!
Ja, es funktioniert tatsächlich so oder so, aber es muss Pass input: as arguments sein , die ich mir in Ihrem Bild nicht angesehen habe, weil ich das automatisch verwende, wenn ich eine for Schleife ausführe .
@jackxujh, ich habe meine Antwort aktualisiert, um auf Ihren Kommentar einzugehen: "Jetzt erstellt der Dienst file.txt.new mit konvertierter Textcodierung, wenn er ausgeführt wird, aber idealerweise wäre file-new.txt noch besser. Ist das auch möglich?"
Ich schätze die Hilfe und Geduld! Es tut mir leid, dass ich Sie mit dieser einfachen Regex- Praxis belästige , über die ich gerade aus Ihrer Antwort mehr erfahren habe.
@jackxujh, kein Problem, dafür waren wir hier, um zu helfen und zu lernen! :) BTW Lesen Sie den Abschnitt Parameter Expansion in der BASH-Manpage.
"${f%.*}-new.${f#*.}"funktioniert nur bei Dateinamen mit genau einem Punkt (in Verzeichnissen, die keine Punkte im Namen haben). Dies richtig zu machen ist überraschend schwierig, aber "${f%.*}-new.${f##*.}"(beachten Sie das Doppel- #) behandelt mehrere Punkte richtig (obwohl es immer noch durch Dateinamen ohne Punkte verwirrt wird).
@Gordon Davisson, das ist gut zu wissen. Wenn Sie dies in der Antwort bearbeiten möchten, können Sie dies gerne tun.
@ user3439894 Ich habe es erweitert, um so ziemlich alles zu handhaben - Sie können jederzeit zurückkehren, wenn Sie der Meinung sind, dass dies zu viele Änderungen gegenüber Ihrer Version sind.
@Gordon Davisson, danke für den Hinweis auf ein Problem im Code! Ich habe die Antwort geändert, um Ihren ersten Kommentar anders anzusprechen als Ihre Bearbeitung, Entschuldigung. #Übrigens hatte ich versehentlich a in meiner ursprünglichen modifizierten Antwort auf die Adresse jackxujh ausgelassen, die -newvor der Erweiterung sein wollte, es war wirklich ein Tippfehler, als ich zu geändert habe, "${filename##*.}"obwohl "${f#*.}"es natürlich hätte sein sollen "${f##*.}". Aber selbst damit würde es fehlschlagen, wenn der Dateiname keine Erweiterung hätte. Das Testen darauf hätte also Teil des Codes sein sollen, und ich habe es in eine Methode geändert, die ich bevorzuge. Danke noch einmal!