不能將 cut -c
(--characters
) 與 UTF-8 一起使用?
該命令
cut
具有-c
處理字元的選項,而不是帶有選項的字節-b
。但這似乎不起作用,在en_US.UTF-8
語言環境中:第二個字節給出了第二個 ASCII 字元(在 UTF-8 中編碼相同):
$ printf 'ABC' | cut -b 2 B
但在 UTF-8 語言環境中不給出三個希臘非 ASCII 字元中的第二個:
$ printf 'αβγ' | cut -b 2 �
沒關係 - 這是第二個字節。
所以我們看第二個字元:
$ printf 'αβγ' | cut -c 2 �
那看起來壞了。
通過一些實驗,結果表明範圍
3-4
顯示了第二個字元:$ printf 'αβγ' | cut -c 3-4 β
但這與字節 3 到 4 相同:
$ printf 'αβγ' | cut -b 3-4 β
所以
-c
不超過-b
UTF-8 的。我希望語言環境設置不適合 UTF-8,但相比之下,
wc
可以按預期工作;它通常用於計算字節數,帶有選項
-c
(--bytes
)。 (注意令人困惑的選項名稱。)$ printf 'αβγ' | wc -c 6
但它也可以使用選項
-m
(--chars
) 計算字元,這很有效:$ printf 'αβγ' | wc -m 3
所以我的配置似乎還可以——但有些特別之處
cut
。也許它根本不支持 UTF-8?但它似乎確實支持多字節字元,否則它不需要支持
-b
and-c
。那麼,怎麼了?為什麼?
據我所知,語言環境設置看起來適合 utf8:
$ locale LANG=en_US.UTF-8 LANGUAGE=en_US LC_CTYPE=en_US.UTF-8 LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" LC_ALL=
輸入,逐字節:
$ printf 'αβγ' | hd 00000000 ce b1 ce b2 ce b3 |......| 00000006
你還沒有說
cut
你正在使用哪個,但既然你提到了 GNU long 選項--characters
,我會假設它就是那個。在這種情況下,請注意以下段落info coreutils 'cut invocation'
:‘-c character-list’ ‘--characters=character-list’
選擇僅列印字元列表中列出的位置中的字元。和現在****一樣
-b
,但國際化會改變這一點。(重點補充)
目前,GNU
cut
始終根據單字節“字元”工作,因此您看到的行為是預期的。POSIX 需要同時支持
-b
和-c
選項——它們沒有被添加到 GNU 中,因為它支持多字節並且它們工作正常,但是為了避免在符合 POSIX 的輸入上出現錯誤。在其他一些實現中也是如此,儘管至少在FreeBSD和OS X中沒有。cut``-c``cut
這是歷史的行為。新添加來接管字節角色,以便可以處理多字節字元。也許幾年後它會始終如一地工作,儘管進展並不是很快(已經十多年了)。GNU甚至還沒有實現該選項,儘管它是正交的並且旨在幫助過渡。舊腳本存在潛在的兼容性問題,這可能是一個問題,儘管我不確定原因是什麼。
-c``-b``-c``cut
-n