Ich möchte tail -f
eine Datei, aber ihr Inhalt ist sjis
kodiert, also muss ich sie in die native Kodierung (UTF-8) meines Terminals konvertieren.
Wenn ich das tue
tail -fx | iconv -fsjis
es wird keine Ausgabe geben.
Schwanz x | iconv -fsjis
funktioniert, zuerst dachte ich, es sei ein Pufferproblem, aber beim Versuch unbuffer
und stdbuf
wie beschrieben aufPufferung in der Pipe deaktivierenhat nicht geholfen.
Tatsächlich würde es sogar nach dem Hinzufügen von mehr als 10 KB Daten zu x keine Ausgabe geben, daher gehe ich davon aus, dass es sich nicht um ein Pufferproblem handelt (der Puffer ist 4 KB groß, wenn ich mich nicht irre), sondern dass iconv erst mit der Ausgabe beginnt, wenn es ein EOF empfängt.
Wie kann ich also meiner mit SJIS codierten Datei am Ende folgen?
Antwort1
(das sollte man nicht allzu ernst nehmen) Soweit ich mich erinnere, liegt das Problem in der Funktionsweise libiconv
. Mehrbyte-Kodierungen benötigen eine Zustandsmaschine, um sie zu dekodieren, und libiconv
sie empfangen am liebsten ganze Zeichen. Sie können ihr also nicht einfach in einem Funktionsaufruf ein halbes Zeichen und im nächsten die andere Hälfte geben.
Mir fallen noch zwei weitere Lösungen ein, eine ist eine gute Out-of-Band-Methode, die andere ist ein In-Band-Hack.
Terminalemulator-Kodierung ändern (Out-of-Band): Eine Möglichkeit besteht darin, die Zeichenkodierung in Ihrem Terminalemulator zu ändern, sodass die native Kodierung Shift JIS ist. Ich habe gerade nachgesehen konsole
und es unterstützt dies. Wählen Sie im Menü Ansicht→Zeichenkodierung→Japanisch→sjis. Sie können dann einfach tail -f
die Datei öffnen und konsole
sich um die Dekodierung der Multibyte-Zeichen und deren Zuordnung zu Schriftglyphen kümmern.
Transkodierung der Terminalkodierung im laufenden Betrieb (In-Band; am besten): mit freundlicher Genehmigung von Gilles, der mich luit
nach langer Zeit daran erinnert hat. Verwenden Sie luit
, das mit Ihrer XOrg-Distribution geliefert werden 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 in/aus Ihrer Terminalkodierung transkodieren und ausführen tail -f x
. Der Nachteil von luit
ist, dass es nicht die Fülle von Kodierungen unterstützt, die von unterstützt werden libiconv
. Der Vorteil ist, dass es fast überall verfügbar ist.
Transkodierung der Terminalkodierung im laufenden Betrieb (In-Band; Hack):ttyconv
ist ein Hack, den ich vor vielen Jahren geschrieben habe(zunächst in C, später in Python überarbeitet), das libiconv
zur Transkodierung der Terminal-E/A verwendet wird. Es erzeugt ein neues Pseudoterminal und (a) transkodiert die Zeichen, die Sie eingeben, von Ihrer lokalen Kodierung in die Remote-Kodierung und (b) transkodiert die Zeichen, die Sie empfangen, von der Remote-Kodierung in Ihre lokale Kodierung. Ich habe es verwendet, um mit Servern zu kommunizieren, die Kodierungen verwendeten, die von den Standard-Linux-Terminals nicht unterstützt werden. Bitte beachten Sie, dass alle Remote-Kodierungen, mit denen ich es getestet habe, Einzelbyte-Kodierungen waren, daher kann ich nicht garantieren, dass es für Shift JIS funktioniert. Ich finde heutzutage nicht oft Anlass, es zu verwenden, da die meisten Systeme auf Unicode umsteigen.
So würden Sie es verwenden:
$ ttyconv -rsjis -- tail -f x
Der Nachteil ttyconv
ist, dass ich es geschrieben habe, niemand außer mir es verwendet und es wahrscheinlich voller Fehler ist. Ich bin darin hervorragend. Der Vorteil ist, dass es verwendet libiconv
, also ist es Ihre beste Wahl, wenn Ihre Kodierung ungewöhnlich ist. Bei der letzten Zählung ttyconv --list
werden 100 Kodierungen unterstützt.
Antwort2
Ähnlich ttyconv
ist auch tconv
, geschrieben in C von Rich Felker.