折疊的 unicode 安全替代品
我
fold -w 3
用來將一行分成多個 3 個字元長,但是對於 GNU 實現,它似乎不適用於具有多字節字元的文本。我怎樣才能實現上述目標
sed
?我想出了
sed -r 's/^(.{0,3})(.*)/\1\n\2/g'
但是這只做了一個替換:echo "111222333444555666" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' 111 222333444555666
其他範例:
echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' ĄĄĄ ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ
並
fold
伴隨著腐敗行為:echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | fold -w 3 Ą� �Ą Ą� �Ą Ą�
簡短**
grep
**的方法:echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | grep -Eo '.{1,3}' ĄĄĄ ĄĄĄ ĄĄĄ ĄĄĄ ĄĄĄ ĄĄĄ ĄĄĄ ĄĄ
僅保留 3 字元序列:
... | grep -Eo '.{3}'
請注意,問題不在於 Unicode 字元集,而在於以 2 個或更多字節編碼的字元(以及寬度不是一個單元格的字元)。
UTF-8 是一種 Unicode 編碼,其中字元 U+0080 到 U+10FFFFF 在 2 個或更多字節上編碼。Unicode 字元 U+0000 到 U+007F 與 ASCII 相同,在 UTF-8 中編碼為單個字節(與 ASCII 相同),在這裡不是問題。
Unicode 字元集還有其他編碼(如 iso8859-1,單字節,但僅限於字元 U+0000 到 U+00FF,或 GB18030,多字節),還有其他多字節的非 Unicode 字元集編碼。
locale charmap
您可以使用該命令來判斷您的語言環境中使用的字元編碼。目前的 GNU 實現
fold
僅適用於單字節字元。fold
大多數其他系統都沒有這個問題。許多甚至可以處理顯示寬度為零或雙倍的字元。自 2010 年以來,busybox 的實現
fold
一直支持 UTF-8(雖然不是其他多字節字元映射)。
- 在 FreeBSD 或 Solaris 上:
$ echo $'a\u0301bcde' | fold -w3 ábc de
- 使用busybox折疊:
$ echo $'a\u0301bcde' | busybox fold -w3 áb cde
- 使用 GNU 折疊:
$ echo $'a\u0301bcde' | fold -w3 á bcd e
U+0301 是一個組合的重音。它有一個空寬度,在 UTF-8 中編碼為 2 個字節(0xcc 0x81)。所以,那個
á
($'a\u0301'
) 是一個寬度為 1 的字素群,由 3 個字節上編碼的 2 個字元組成,因此有 3 種不同的行為,其中最正確的是 FreeBSD/Solaris’ 這裡。
grep
使用PCRE 支持、UTF-8 語言環境和 UTF-8 輸入建構的GNU :grep -Po '\X{1,3}'
o
在輸入的每一行上輸出1 到 3 個(盡可能多)的所有序列,X
可能會給你更好的結果,比如上面的情況,你將標記與單寬字元組合在一起。如果有雙角字元或零與未與單角字元組合的字元或有 TAB、CR、BS 等控製字元,則無濟於事。