我想要tail -f
一个文件,但它的内容是sjis
编码的,所以我需要将它转换为我的终端的本机 (utf-8) 编码。
当我做
尾-fx | iconv -fsjis
不会有输出。作为
尾巴 x | iconv -fsjis
确实有效,起初我认为这是一个缓冲问题,但尝试unbuffer
并stdbuf
按照关闭管道中的缓冲没有帮助。
实际上,即使在 x 中添加了 10k 以上的数据,也不会有输出,所以我想这不是缓冲问题(缓冲区是 4k,如果我没记错的话),但是 iconv 只会在它收到一个EOF。
那么我怎样才能跟随我的 sjis 编码文件呢?
Ale*_*ios 12
(加一点盐)据我所知,问题在于工作方式libiconv
。多字节编码需要一个状态机来解码它们,并且libiconv
更喜欢接收整个字符,所以你不能在一个函数调用中只给它半个字符,而在下一个函数调用中给它另一半。
我可以想到另外两种解决方案,一种是很好的带外方法,另一种是带内黑客。
更改终端仿真器编码(带外):一种是更改终端仿真器中的字符编码,因此其本机编码为 Shift JIS。我刚刚检查过konsole
,并且支持这一点。从菜单中,查看?字符编码?日本语?sjis。然后tail -f
,您可以只使用该文件,并konsole
负责解码多字节字符并将它们与字体字形匹配。
即时转码终端编码(带内;最佳):由 Gilles 提供,他luit
在很长一段时间后提醒我。使用luit
,它应该与您的 XOrg 发行版一起提供(在 Debian 上,它是 package x11-utils
)。像这样使用它:
$ luit -encoding SJIS -- tail -f x
Run Code Online (Sandbox Code Playgroud)
这将使终端将 SJIS 转码为/从您的终端编码,并运行tail -f x
. 缺点luit
是它不支持libiconv
. 好处是它几乎无处不在。
即时转码终端编码(带内;hack):ttyconv
是我多年前写的一个 hack(最初用 C,后来用 Python 重做),用于libiconv
对终端 I/O 进行转码。它生成一个新的伪终端,并且 (a) 将您键入的字符从本地编码转码为远程编码,以及 (b) 将您从远程编码接收到的字符转码为本地编码。我用它来与使用标准 Linux 终端不支持的编码的服务器通信。请注意,我测试的所有远程编码都是单字节编码,所以我不能保证它适用于 Shift JIS。这些天我不经常使用它,因为大多数系统都切换到 Unicode。
这是你将如何使用它:
$ ttyconv -rsjis -- tail -f x
Run Code Online (Sandbox Code Playgroud)
缺点ttyconv
是我写了它,除了我没有人使用它,它可能充满了错误。我擅长这一点。好处是它使用libiconv
,所以如果你的编码不寻常,这是你最好的选择。最后统计,ttyconv --list
支持 100 种编码。