我想要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