Tools zum Konvertieren von 8-Bit-C1-Steuerzeichen in ESC-Sequenzen?

446
Rehno Lindeque

Der ECMA-48-Standard ("ANSI-Escape-Sequenzen") beschreibt zwei Möglichkeiten, den C1-Satz von Steuercodes zu codieren: Verwendung von 2-stelligen ESC-Sequenzen oder alternativ von 8-Bit-Steuerzeichen.

Wikipedia-Artikel erklären, dass die zweizeiligen ESC-Sequenzen besser für UTF-8 geeignet sind.

Zitieren aus ANSI-Escape-Code :

Der Standard besagt, dass diese 2-Byte-Sequenzen in 8-Bit-Umgebungen zu einem C1-Steuercode im Bereich 0x80–0x9F zusammengeführt werden können. Bei modernen Geräten werden diese Codes jedoch häufig für andere Zwecke verwendet, z. B. für Teile von UTF-8 oder für CP-1252-Zeichen. Daher wird nur die 2-Byte-Sequenz verwendet.

und von den Steuercodes C0 und C1 :

Die C1-Zeichen in Unicode erfordern, dass 2 Byte in UTF-8 codiert werden (z. B. wird CSI bei U + 009B als Bytes 0xC2, 0x9B in UTF-8 codiert). Daher wird häufiger auf die entsprechenden Steuerfunktionen unter Verwendung der äquivalenten Zwei-Byte-Escape-Sequenz zugegriffen, die zur Verwendung mit Systemen gedacht ist, die nur 7-Bit-Bytes haben.


Gibt es Befehlszeilentools, mit denen 8-Bit-C1-Steuerzeichen (gemäß ECMA-48) direkt in zweistellige ESC-Sequenzen umgewandelt werden können?

Mein bisher bester Versuch war zu versuchen und zu verwenden iconv:

$ printf $(echo -en "\x9b") | iconv --from-code=ANSI_X3.4 --to-code=UTF-8 | od -t x1 iconv: illegal input sequence at position 0 

Für Debugging-Zwecke verwende ich od -t x1, um das Ergebnis wieder in Hexadezimalformat zu rendern. Das Ergebnis, das ich erhoffe, wäre dasselbe wie das Ergebnis des Laufens:

$ printf $(echo -en "\x27[") | od -t x1 0000000 27 5b 0000002 

Gibt es mit anderen Worten ein Befehlszeilentool, mit dem Sie ein C1-Steuerzeichen wie Pipe einleiten \x9bund eine Escape-Sequenz wie erhalten können \x27[?

BEARBEITEN: Oder wie egmont zu Recht eher ein interaktives Werkzeug vorschlägt als etwas, in das Sie hineinpfeifen.

2
Könnten Sie bitte etwas mehr über das Gesamtproblem berichten? Woher kommen die Daten? Ist es eine ältere Anwendung, die Sie nicht ändern können? Behandelt es Nicht-ASCII-Zeichen? Wenn ja, in welcher Kodierung? Warum müssen Sie von C1 nach C0 konvertieren? Funktioniert diese App nicht in einem Terminalemulator? Suchen Sie wirklich ein Befehlszeilentool, das "Offline" -Daten verarbeitet, oder benötigen Sie eine Laufzeitkonvertierung (wie z. B. "luit" dies tun würde, wenn es eine solche Option hätte)? Was ist eigentlich das Problem, das Sie beheben möchten? egmont vor 6 Jahren 1
@egmont luit scheint vielversprechend. Ich werde mich melden, wenn es für meine Zwecke funktioniert. Ich denke, dass es sich lohnt, in diesem Fall zu einer Antwort zu werden. Ich arbeite an einer Terminalautomationssoftware, die ein Pseudo-Terminal verwendet, um eine Verbindung zu einer Remote-Maschine mit Legacy-Software herzustellen (etwas schwierig in die Details zu kommen). Suchen Sie grundsätzlich nach einer Abkürzung, um den C1-Zeichensatz separat zu konvertieren, um stattdessen moderne ESC-Codes zu verwenden. Rehno Lindeque vor 6 Jahren 0
Für die Abstimmende: Ich habe viel Zeit damit verbracht, Google zu lesen und nach dem richtigen Werkzeug zu suchen. Ich habe auch einen Abschnitt geschrieben, in dem es darum geht, warum eine Konvertierung von C1-Zeichen in ESC-Sequenzen wünschenswert ist (Inkompatibilität mit UTF-8). Bitte lassen Sie mich wissen, ob es etwas gibt, das ich dankend verbessern kann! Rehno Lindeque vor 6 Jahren 1
Ich muss übrigens nicht von C1 nach C0 konvertieren. Vielmehr erfolgt die Konvertierung vom 8-Bit-C1-Zeichensatz (Einzelzeichen) in die entsprechende 2-Zeichen-Escape-Sequenz, die ursprünglich für 7-Bit-Umgebungen vorgesehen war, jetzt jedoch häufiger auftritt, da der 8-Bit-C1-Zeichensatz überlappt mit UTF-8. Ich hoffe das hilft ein wenig zu klären. Rehno Lindeque vor 6 Jahren 0
Zu deinem letzten Kommentar: In diesem Fall brauchst du nur eine ISO-8859-1 (aka Latin-1) -> UTF-8-Zeichensatzkonvertierung, die möglicherweise von `luit` ausgeführt wird. egmont vor 6 Jahren 0
Beachten Sie, dass nicht alle Terminal-Emulatoren C1 in UTF-8 unterstützen. Siehe beispielsweise http://invisible-island.net/xterm/ctlseqs/ctlseqs.html, warum xterm dies nicht tut. egmont vor 6 Jahren 0
Wenn Sie noch eine C1-> C0-Konvertierung benötigen, würde ich wahrscheinlich "luit" patchen. Alle Befehlszeilentools wie "iconv" oder "sed" haben den Nachteil, dass sie nicht als Terminals gegenüber den Apps erscheinen, die die Ausgabe generieren (die Eingabe für diese Tools). Außerdem führen sie Zeilenpufferung oder 4-KB-Pufferung für ihre Ausgabe aus. Stattdessen benötigen Sie etwas, das sich wie ein Terminal verhält, den Stream ohne Pufferung filtert und andere Dinge (z. B. Fenstergröße) des Terminals transparent weiterleitet. Es ist umständlich, diese richtig zu machen. Wenn Sie Luit patchen, können Sie Ihre Änderungen sogar Upstream hinzufügen. egmont vor 6 Jahren 0
Ich komme langsam zu dem Schluss, dass weder `iconv` noch` luit` die C1-Zeichen unterstützen. Sie sind nicht Teil von ISO 8859-1, sondern scheinen [undefiniert im Code-Seiten-Layout] (https://en.wikipedia.org/wiki/ISO/IEC_8859-1#Code_page_layout) zu sein. In der "luit" -Manpage heißt es: "Die Auswahl alternativer Gruppen von Steuerzeichen wird nicht unterstützt und wird es niemals sein." Rehno Lindeque vor 6 Jahren 1
Auf der anderen Seite heißt es in [ISO 8859-1 in luit] (https://invisible-island.net/luit/luit-figures.html#iso_charsets): "Beachten Sie, dass 0x80-0x9f" n / a "ist ( nicht verfügbar), da die ISO-Kodierung diese für C1-Steuerungen reserviert. " Rehno Lindeque vor 6 Jahren 1
So haben meine Hauptversuche für iconv ausgesehen: `printf" \ n \ x9B \ n "| iconv --from-code = ISO8859-1 --to-code = UTF-8 | od -t x1` und für luit: `printf" \ n \ x9B \ n "| luit -c-kodiert nach ISO-8859-1 | od -t x1`. Rehno Lindeque vor 6 Jahren 0
Es tut mir leid, dass "luit" nicht so funktioniert hat, wie ich es erwartet hatte. Vielleicht ist das Patchen für diese Codepunkte der einfachste Weg. Nur für die Konvertierung können Sie leicht eine "sed" -Befehlszeile aufbauen, die alle möglichen C1-Bytes einzeln konvertiert. Dies würde jedoch unter den Pufferproblemen leiden, die sich nicht für eine Laufzeitlösung eignen. egmont vor 6 Jahren 0
Danke für die Hilfe auf jeden Fall @egmont, ich schätze es. Keine Sorge, ich habe alternative Ideen, ein Standardwerkzeug war nur meine erste Wahl. (Übrigens, was die Pufferung angeht, denke ich, dass "sed -u" oder "unbuffer -p" Optionen sein könnten.) Rehno Lindeque vor 6 Jahren 1
Sagen Sie uns Bescheid, wenn Sie etwas schaffen. Viel Glück! egmont vor 6 Jahren 0

0 Antworten auf die Frage