"Schwanz -f | iconv -fsjis ”gibt nichts aus

14

Ich möchte tail -feine Datei, deren Inhalt sich jedoch in sjisCodierung befindet. Daher muss sie in die native (utf-8) Codierung meines Terminals konvertiert werden.

Wenn ich es tue

Schwanz -fx | iconv -fsjis

Es erfolgt keine Ausgabe. Wie

Schwanz x | iconv -fsjis

funktioniert, zuerst dachte ich , es ist ein Puffer Problem war, sondern versuchen , unbufferund stdbufwie beschrieben in Rohr Schalten Sie Pufferung hat nicht geholfen.

Selbst nachdem mehr als 10.000 Daten zu x hinzugefügt wurden, würde es keine Ausgabe geben. Ich denke, es handelt sich nicht um ein Pufferproblem (der Puffer ist 4.000, wenn ich mich nicht irre), aber iconv wird erst mit der Ausgabe beginnen, wenn es erhält eine EOF.

Wie kann ich also meine sjis-verschlüsselte Datei verfolgen?

Eugene Beresovsky
quelle

Antworten:

11

(Nimm das mit einer Prise Salz) Soweit ich mich erinnere, liegt das Problem in der Funktionsweise libiconv. Multibyte-Codierungen benötigen eine Zustandsmaschine, um sie zu decodieren, und libiconvbevorzugen den Empfang ganzer Zeichen. Sie können sie also nicht einfach in einem Funktionsaufruf und in der nächsten Hälfte einem halben Zeichen zuweisen.

Ich kann mir zwei andere Lösungen vorstellen, eine ist eine gute Out-of-Band-Methode, die andere ist ein In-Band-Hack.

Ändern der Terminal-Emulator-Codierung (außerhalb des Bandes) : Eine besteht darin, die Zeichencodierung in Ihrem Terminal-Emulator zu ändern, sodass die systemeigene Codierung Shift JIS lautet. Ich habe gerade nachgesehen konsoleund unterstütze dies. Wählen Sie im Menü Ansicht → Zeichenkodierung → Japanisch → sjis. Sie können dann nur tail -fdie Datei und konsolekümmern sich um die Dekodierung der Multibyte-Zeichen und deren Zuordnung zu Schriftzeichen.

Transcode-Terminal-Codierung im laufenden Betrieb (In-Band; am besten) : Mit freundlicher Genehmigung von Gilles, der mich luitnach sehr langer Zeit daran erinnert hat . Verwenden Sie luit, was mit Ihrer XOrg-Distribution hätte kommen sollen (unter Debian ist es das Paket x11-utils). Benutze es so:

$ luit -encoding SJIS -- tail -f x

Dies veranlasst das Terminal, SJIS von / zu Ihrer Terminalkodierung zu transkodieren und auszuführen tail -f x. Der Nachteil luitist, dass es nicht die Fülle der von unterstützten Codierungen unterstützt libiconv. Der Vorteil ist, dass es fast überall verfügbar ist.

Transcode-Terminal-Codierung im laufenden Betrieb (In-Band; Hack) : Dies ttyconvist ein Hack, den ich vor vielen Jahren geschrieben habe (zunächst in C, später in Python überarbeitet) und mit libiconvdem Terminal-E / A-Vorgänge transcodiert werden. Es wird ein neues Pseudoterminal erzeugt und (a) die von Ihnen eingegebenen Zeichen aus Ihrer lokalen Codierung in die Ferncodierung umcodiert und (b) die von der Ferncodierung empfangenen Zeichen in Ihre lokale Codierung umcodiert. Ich habe damit mit Servern gesprochen, die Kodierungen verwendeten, die von den Standard-Linux-Terminals nicht unterstützt werden. Bitte beachten Sie, dass alle Remote-Codierungen, mit denen ich es getestet habe, Einzelbyte-Codierungen waren, sodass ich nicht garantieren kann, dass es für Shift JIS funktioniert. Ich finde heutzutage nicht oft einen Anruf, um es zu verwenden, da die meisten Systeme auf Unicode umsteigen.

So würden Sie es verwenden:

$ ttyconv -rsjis -- tail -f x

Der Nachteil ttyconvist, dass ich es geschrieben habe, niemand benutzt es außer mir, es ist wahrscheinlich voller Fehler. Darin bin ich herausragend. Der Vorteil ist, dass es verwendet libiconvwird. Wenn Ihre Codierung also ungewöhnlich ist, ist es die beste Wahl. Bei der letzten Zählung ttyconv --listwerden 100 Codierungen unterstützt.

Alexios
quelle
Super, danke. out-of-band hat bei mir nicht funktioniert (gnome-terminal, obwohl es Ihnen erlaubt, die Kodierung zu ändern), aber ttyconv funktioniert wie ein Zauber.
Eugene Beresovsky
2
Heutzutage gibt es einen luitTeil der Standard-X11-Utility-Suite, der Ihrem ähnlich ist ttyconv.
Gilles 'SO- hör auf böse zu sein'
@Gilles luitist ähnlich, außer dass es weitaus besser funktioniert als meins. ;) Vielen Dank! Deshalb habe ich aufgehört zu benutzen. In den 12 Jahren seitdem habe ich es geschafft, sogar den Befehlsnamen zu vergessen und seitdem habe ich danach gesucht.
Alexios
@ Gilles luitfunktioniert auch für mich. Warum machst du es nicht zu einer "offiziellen" Antwort? Es war Teil meiner Installation (Debian) und ist daher für mich am einfachsten zu benutzen.
Eugene Beresovsky
1
Ich habe die Antwort so aktualisiert, dass sie luitdie beste Wahl für SJIS ist. Leider scheint es nicht jede Kodierung zu libiconvunterstützen. Es sieht so aus, als müsste ich meine eigene Lösung für meine eigenen surrealen Zwecke verwenden. :)
Alexios