Ich möchte tail -f
ausführen eine Datei, aber ihr Inhalt ist in sjis
Codierung, also muss ich es in die native (utf-8) Codierung meines Terminals konvertieren lassen.
Wenn ich das tue
Schwanz -f x | iconv -fsjis
es erfolgt keine Ausgabe. Als
Schwanz x | iconv -fsjis
funktioniert, zuerst dachte ich, es sei ein Pufferproblem, aber ich versuche unbuffer
und stdbuf
wie beschrieben unter Pufferung in Pipe ausschalten hat nicht geholfen.
Tatsächlich würde es keine Ausgabe geben, selbst nachdem mehr als 10k Daten zu x hinzugefügt wurden, also denke ich, dass es sich nicht um ein Pufferproblem handelt (Puffer ist 4k, wenn ich mich nicht irre), aber iconv beginnt erst dann mit der Ausgabe, wenn es erhält ein EOF.
Wie kann ich also meiner Sjis-codierten Datei folgen?
Akzeptierte Antwort:
(Nehmen Sie das mit einer Prise Salz) Soweit ich mich erinnere, liegt das Problem in der Art und Weise libiconv
funktioniert. Multi-Byte-Codierungen benötigen eine Zustandsmaschine, um sie zu decodieren, und libiconv
bevorzugt ganze Zeichen, also kann man ihm nicht einfach ein halbes Zeichen in einem Funktionsaufruf geben und die andere Hälfte im nächsten.
Mir fallen zwei weitere Lösungen ein, eine ist eine gute Out-of-Band-Methode, die andere ein In-Band-Hack.
Ändern Sie die Codierung des Terminal-Emulators (außerhalb des Bandes) :Eine besteht darin, die Zeichencodierung in Ihrem Terminalemulator zu ändern, sodass die native Codierung Shift JIS ist. Ich habe gerade konsole
überprüft , und unterstützt dies. Wählen Sie im Menü Ansicht→Zeichenkodierung→Japanisch→sjis. Sie können dann einfach tail -f
verwenden die Datei und konsole
kümmert sich um die Dekodierung der Multibyte-Zeichen und ordnet sie den Font-Glyphen zu.
Terminalcodierung on-the-fly transcodieren (in-band; am besten) :Mit freundlicher Genehmigung von Gilles, der mich an luit
erinnerte nach sehr langer Zeit. Verwenden Sie luit
, das in Ihrer XOrg-Distribution enthalten sein sollte (unter Debian ist es das Paket x11-utils
). Verwenden Sie es wie folgt:
$ luit -encoding SJIS -- tail -f x
Dadurch wird das Terminal SJIS zu/von Ihrer Terminalcodierung transcodieren und tail -f x
ausführen . Die Kehrseite von luit
ist, dass es nicht die Fülle von Kodierungen unterstützt, die von libiconv
unterstützt werden . Der Vorteil ist, dass es fast überall verfügbar ist.
Terminalkodierung on-the-fly transkodieren (in-band; hacken) :ttyconv
ist ein Hack, den ich vor vielen Jahren geschrieben habe (anfangs in C, später in Python überarbeitet), der libiconv
verwendet um Terminal-E/A zu transcodieren. Es erzeugt ein neues Pseudoterminal und (a) transkodiert die Zeichen, die Sie von Ihrer lokalen Kodierung in die Remote-Kodierung eingeben, und (b) transkodiert die Zeichen, die Sie von der Remote-Kodierung erhalten, in Ihre lokale Kodierung. Ich habe es verwendet, um mit Servern zu sprechen, die Codierungen verwendeten, die von den Standard-Linux-Terminals nicht unterstützt wurden. Bitte beachten Sie, dass alle Remote-Codierungen, mit denen ich es getestet habe, Einzelbyte-Codierungen waren, daher kann ich nicht garantieren, dass es für Shift JIS funktioniert. Heutzutage finde ich nicht oft einen Aufruf, es zu verwenden, da die meisten Systeme auf Unicode umstellen.
So würden Sie es verwenden:
$ ttyconv -rsjis -- tail -f x
Die Kehrseite von ttyconv
ist, dass ich es geschrieben habe, niemand außer mir es benutzt, es ist wahrscheinlich voller Fehler. Darin bin ich ausgezeichnet. Der Vorteil ist, dass es libiconv
verwendet , wenn Ihre Codierung also ungewöhnlich ist, ist sie die beste Wahl. Letzte Zählung, ttyconv --list
unterstützt 100 Kodierungen.