"Cola -f | iconv -fsjis "no muestra nada

14

Quiero tail -fun archivo, pero su contenido está en sjiscodificación, por lo que necesito convertirlo a la codificación nativa (utf-8) de mi terminal.

Cuando lo hago

cola -fx | iconv -fsjis

No habrá salida. Como

cola x | iconv -fsjis

funciona, al principio pensé que era un problema de almacenamiento en búfer, pero intentarlo unbuffery, stdbufcomo se describe en Desactivar el almacenamiento en búfer en la tubería , no ayudó.

De hecho, incluso después de agregar más de 10k de datos a x, no habría salida, por lo que supongo que no es un problema de almacenamiento en búfer (el búfer es 4k, si no me equivoco), pero iconv solo comenzará a salir cuando recibe un EOF.

Entonces, ¿cómo puedo seguir mi archivo codificado sjis?

Eugene Beresovsky
fuente

Respuestas:

11

(tome esto con una pizca de sal) Hasta donde recuerdo, el problema radica en la forma en que libiconvfunciona. Las codificaciones de varios bytes necesitan una máquina de estado para decodificarlas, y libiconvprefiere recibir caracteres completos, por lo que no puede simplemente darle la mitad de un carácter en una llamada de función y la otra mitad en la siguiente.

Puedo pensar en otras dos soluciones, una es un buen método fuera de banda, la otra es un truco dentro de la banda.

Cambiar la codificación del emulador de terminal (fuera de banda) : una es cambiar la codificación de caracteres en su emulador de terminal, por lo que su codificación nativa es Shift JIS. Acabo de comprobar konsole, y es compatible con esto. Desde el menú, Ver → Codificación de caracteres → Japonés → sjis. Entonces puede simplemente tail -fel archivo y konsolese encargará de decodificar los caracteres multibyte y unirlos con los glifos de fuente.

Transcodifique la codificación del terminal sobre la marcha (en banda; mejor) : cortesía de Gilles, quien me recordó luitdespués de mucho tiempo. Use luit, que debería haber venido con su distribución XOrg (en Debian, es un paquete x11-utils). Úselo así:

$ luit -encoding SJIS -- tail -f x

Esto hará que el terminal transcodifique SJIS a / desde su codificación de terminal y se ejecute tail -f x. La desventaja luites que no admite la gran cantidad de codificaciones que admite libiconv. Lo bueno es que está disponible en casi todas partes.

Transcodifique la codificación de terminal sobre la marcha (en banda; pirateo) : ttyconves un truco que escribí hace muchos años (inicialmente en C, luego rehecho en Python) que se usa libiconvpara transcodificar E / S de terminal. Genera un nuevo pseudoterminal y (a) transcodifica los caracteres que escribe de su codificación local a la codificación remota, y (b) transcodifica los caracteres que recibe de la codificación remota a su codificación local. Lo usé para hablar con servidores que usaban codificaciones no compatibles con los terminales estándar de Linux. Tenga en cuenta que todas las codificaciones remotas con las que lo probé eran codificaciones de un solo byte, por lo que no puedo garantizar que funcione para Shift JIS. A menudo no encuentro llamadas para usarlo en estos días, con la mayoría de los sistemas cambiando a Unicode.

Así es como lo usarías:

$ ttyconv -rsjis -- tail -f x

La desventaja ttyconves que lo escribí, nadie lo usa sino yo, probablemente esté lleno de errores. Me destaco en esto. Lo bueno es que usa libiconv, por lo que si su codificación es inusual, es su mejor opción. En el último recuento, ttyconv --listadmite 100 codificaciones.

Alexios
fuente
Genial gracias. fuera de banda no funcionó para mí (gnome-terminal, aunque sí le permite cambiar la codificación), pero ttyconv funciona de maravilla.
Eugene Beresovsky
2
En estos días, hay luitparte de la suite de utilidades X11 estándar, que es similar a la suya ttyconv.
Gilles 'SO- deja de ser malvado'
@Gilles luites similar, excepto que funciona mucho mejor que el mío. ;) ¡Gracias! Es por eso que dejé de usar en primer lugar. En los 12 años transcurridos desde que logré olvidar incluso el nombre del comando y lo he estado buscando desde entonces.
Alexios
@Gilles también luitfunciona para mí. ¿Por qué no lo conviertes en una respuesta 'oficial'? Era parte de mi instalación (debian) y, por lo tanto, es la más fácil de usar para mí.
Eugene Beresovsky
1
Actualicé la respuesta para incluirla luitcomo la mejor opción para SJIS. Lamentablemente, parece que no admite todas las codificaciones libiconv. Parece que todavía tengo que usar mi propia solución para mis propios fines surrealistas. :)
Alexios