Voglio tail -f
un file, ma il suo contenuto è in sjis
codifica, quindi devo averlo convertito nella codifica nativa (utf-8) del mio terminale.
Quando lo faccio
coda -f x | iconv -fsjis
non ci sarà alcun output. Come
coda x | iconv -fsjis
funziona, all'inizio pensavo fosse un problema di buffering, ma ho provato unbuffer
e stdbuf
come descritto in Disattivare il buffering nella pipe non ha aiutato.
In effetti, anche dopo che sono stati aggiunti più di 10k di dati a x, non ci sarebbe alcun output, quindi suppongo che non sia un problema di buffering (il buffer è 4k, se non sbaglio), ma iconv inizierà a produrre solo quando riceve un EOF.
Quindi, come posso seguire il mio file codificato sjis?
Risposta accettata:
(prendilo con le pinze) Per quanto mi ricordo, il problema sta nel modo in cui libiconv
lavori. Le codifiche multi-byte richiedono una macchina a stati per decodificarle e libiconv
preferisce ricevere interi caratteri, quindi non puoi semplicemente assegnargli metà carattere in una chiamata di funzione e l'altra metà nella successiva.
Mi vengono in mente altre due soluzioni, una è un buon metodo fuori banda, l'altra è un hack in banda.
Modifica la codifica dell'emulatore di terminale (fuori banda) :uno è cambiare la codifica dei caratteri nell'emulatore di terminale, quindi la sua codifica nativa è Shift JIS. Ho appena controllato konsole
, ed è supporta questo. Dal menu, Visualizza→Codifica caratteri→Giapponesi→sjis. Puoi quindi semplicemente tail -f
il file e konsole
si occuperà di decodificare i caratteri multibyte e di abbinarli ai glifi dei caratteri.
Transcodifica al volo la codifica del terminale (in-band; migliore) :per gentile concessione di Gilles, che mi ha ricordato luit
dopo molto tempo. Usa luit
, che dovrebbe essere arrivato con la tua distribuzione XOrg (su Debian, è il pacchetto x11-utils
). Usalo in questo modo:
$ luit -encoding SJIS -- tail -f x
In questo modo il terminale transcodificherà SJIS da/verso la codifica del terminale ed eseguirà tail -f x
. Lo svantaggio di luit
è che non supporta la vasta gamma di codifiche supportate da libiconv
. Il vantaggio è che è disponibile quasi ovunque.
Transcodifica al volo la codifica del terminale (in-band; hack) :ttyconv
è un hack che ho scritto molti anni fa (inizialmente in C, poi rifatto in Python) che usa libiconv
per transcodificare l'I/O del terminale. Genera un nuovo pseudoterminale e (a) transcodifica i caratteri digitati dalla codifica locale nella codifica remota e (b) transcodifica i caratteri ricevuti dalla codifica remota nella codifica locale. L'ho usato per parlare con server che utilizzavano codifiche non supportate dai terminali Linux standard. Tieni presente che tutte le codifiche remote con cui l'ho testato erano codifiche a byte singolo, quindi non posso garantire che funzionerebbe per Shift JIS. Non trovo spesso chiamate per usarlo in questi giorni, con la maggior parte dei sistemi che passa a Unicode.
Ecco come lo useresti:
$ ttyconv -rsjis -- tail -f x
Lo svantaggio di ttyconv
è che l'ho scritto io, nessuno lo usa tranne me, probabilmente è pieno di bug. Eccello in questo. Il vantaggio è che utilizza libiconv
, quindi se la tua codifica è insolita, è la soluzione migliore. Alla fine, ttyconv --list
supporta 100 codifiche.