2016-07-30 27 views
1

Ich verwende einen Compiler für eine alte Spielkonsole, aber dieser Compiler akzeptiert nur ANSI-Zeichen. Dies ist ein Problem, da das Spiel auf Japanisch ist und UTF-8 benötigt wird. Als Workaround habe ich ein Batch-Skript geschrieben, das sed ausführt, um jedes japanische Zeichen im Dokument durch den entsprechenden Byte-Wert in Hexadezimalzahl zu ersetzen.sed: Ersetzen jedes Zeichen einzeln zwischen Trennzeichen

Das Haupt sed-Skript sieht wie folgt aus:

chcp 1252 
sed "s|\[terminator\]|,$FF|g"^ 
;"s|ャ|,$00|g"^ 
;"s|ィ|,$01|g"^
test.asm > test2.asm 

So ein String wie "ャ ィ ャ [Terminator]" wird umgewandelt "00, $ 01, $ 00 $, $ FF".

Das Problem ist, dass nicht-japanische Zeichen, die in eine Zeichenfolge eingefügt werden können, wie Ziffern und Satzzeichen, auch überall sonst im Code verwendet werden, so musste ich alternative Versionen dieser Zeichen zu verhindern sed aus der Konvertierung, sagen wir, das Semikolon vor jedem Kommentar, was den Kompilierungsprozess zum Scheitern bringen würde. Diese Problemumgehung zwingt den Benutzer jedoch dazu, jedes dieser alternativen Zeichen in die Zeichenfolge zu kopieren und einzufügen, in der sie Änderungen vornehmen möchten, anstatt sie einfach so einzugeben, wie sie es normalerweise tun würden.

Also ist meine Frage, wie kann ich sed sagen, nur die Zeichen zwischen den Trennzeichen (Pipes) zu ersetzen, anstatt die Ersetzungen überall im Dokument durchzuführen?

Mit anderen Worten, ich möchte sed etwas zu ersetzen, das wie folgt aussieht:

<label> dw $1234 : db |ャィャ[terminator]|  ; Comment (blah ャィャ blah) 

dazu (Rohre und führende Komma wird später entfernt werden):

<label> dw $1234 : db |,$00,$01,$00,$FF|  ; Comment (blah ャィャ blah) 

Hinweis Kommentar Teil bleibt unberührt.

+0

Sie sollten Ihre Frage bearbeiten. Niemand scheint es zu verstehen, oder jemand hätte bereits geantwortet. Dieser Teil ist verwirrend: "Aber ich würde gerne mit dem benutzerfreundlicheren Ansatz fortfahren, die Zeichenketten im Originaldokument zu behalten" –

+0

Fertig. Macht es jetzt mehr Sinn? –

+0

Sicher. Sie haben sogar eine Antwort darauf bekommen, was es zu einer Tumblewee-Frage hätte werden können. –

Antwort

2

Es gibt wahrscheinlich einen Weg, dies in sed zu tun; aber es wird komplex und schwierig zu warten. Mein Vorschlag wäre, zu einer anderen Sprache zu wechseln, wo das einfach ist. Hier ist Awk:

awk -F '|' '{ gsub(/\[terminator]/, "$FF", $2); 
    gsub(/ャ/, ",$00", $2); 
    gsub(/ィ/, ",$01", $2); } 1' test.asm >test2.asm 

Ich bin auf Unix, wo einzelne Anführungsstriche hier am sinnvollsten sind. Ich verstehe, dass CMD doppelte Anführungszeichen bevorzugt, was die Angelegenheit komplizierter macht; im schlimmsten Fall, vielleicht legen Sie das Skript in eine Datei, und rufen Sie es mit awk -F "|" -f scriptfile.awk test.asm >test2.asm

Wenn Sie nicht Awk für Ihre Plattform haben, sollte dies ähnlich einfach in Perl, Python oder Ruby sein. (Perl kommt sogar mit a2p zum Übersetzen Awk-Skripte Perl.)

+0

Danke, ich habe es geschafft, nachdem der Doppelpunkt ganz am Ende entfernt wurde, indem die einfachen Anführungszeichen durch doppelte Anführungszeichen ersetzt und die doppelten Anführungszeichen entfernt wurden. –

+0

Korrigiert den Doppelpunkt Typo; Danke für die Benachrichtigung und danke für das Akzeptieren! – tripleee

+0

Ich habe bemerkt, dass Sie nur der öffnenden eckigen Klammer entkommen sind, aber nicht der schließenden. Ist das ein weiterer Tippfehler oder macht das keinen Unterschied? –

2
echo \ 
    '<address> dw $1234 : db |ャィャ[terminator]|  ; Comment (blah ャィャ blah)' | \ 
sed 's/\[terminator\]/,$FF/; 
    :c1 s/ャ\(.*\)|/,$00\1|/;t c1; 
    :c2 s/ィ\(.*\)|/,$01\1|/;t c2' 

Ausgang:

<address> dw $1234 : db |,$00,$01,$00,$FF|  ; Comment (blah ャィャ blah) 

Wenn gezählt LABEL Namen wie "c1, c2, wirken wie eine Mühe, diejenigen, Katakana auch als eindeutige Bezeichnungen dienen kann:

sed 's/\[terminator\]/,$FF/; 
    :ャ s/ャ\(.*\)|/,$00\1|/;t ャ; 
    :ィ s/ィ\(.*\)|/,$01\1|/;t ィ' 

Hinweise.Es scheint, wie die globaler Option von search gearbeitet haben sollte:

echo abcdabcdabcd | sed 's/a/-/g' 
-bcd-bcd-bcd 

hinzufügen Wildcard und globaler nicht hilft, es ersetzt nur ein "a" mit einem "-":

echo abcdabcdabcd | sed 's/a\(.*\)/-\1/g' 
-bcdabcdabcd 

Eine Schleife funktioniert:

echo abcdabcdabcd | sed ':c1 s/a\(.*\)/-\1/;t c1' 
-bcd-bcd-bcd 
+0

@triplee, bitte seien Sie genauer, wenn Sie einen Fehler gefunden haben. Zur Zeit scheint Ihr Kommentar ein wenig rätselhaft, da die Beispielausgabe bestätigt, dass 1) die gegebene Antwort Kommentare vermeidet und 2) mit doppeltem Katakana zurechtkommt. – agc

+0

Mein schlechtes, ich habe anscheinend etwas vermasselt, als ich es getestet habe. Mein Kommentar wurde entfernt. Das tut mir leid. – tripleee

+0

agc: Danke für den Vorschlag. Ich akzeptierte Tripleees, weil es schneller in der Ausführung schien, aber war versucht, deine anzunehmen, weil ich ursprünglich nach einer sed-spezifischen Lösung gefragt hatte. –

Verwandte Themen