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