我正在开发一个 bash 脚本并发现了以下奇怪的行为!
$ echo £ |cut -c 1
�
该符号£
被传递给下一个命令cut
,该命令的过滤器仅选择一个字符。
当我修改命令中的过滤器cut
以选择 2 个字符时,它就£
通过了!
$ echo £ |cut -c 1-2
£
这不是一个严重的问题,我在脚本中有一个解决方案,但是为什么 cut 命令中的过滤器在选择符号时需要 2 个位置而不是 1 个£
?
答案1
Ubuntu 中的命令cut
不支持多字节字符。字符与字节相同 此版本的cut
命令。
磅号 ( £
) 是一个 UTF-8 字符,由两个字节 (c2
和a3
) 组成:
$ echo £ | od -t x1
0000000 c2 a3 0a
0000003
笔记:该0a
字符是“新行”(ASCII“换行符”)。
当您cut
从行中选取第一个字符时,您仅选择了c2
的部分£
,而这不是有效的 UTF-8 字符。因此,您会看到奇怪的问号�
(替换字符) 在屏幕上:
$ echo £ | cut -c 1 | od -t x1
0000000 c2 0a
0000002
笔记cut
:以上内容已在 Ubuntu 20.10的最新版本中进行了测试(GNU coreutils 版本 8.32)。
如果要选择多字节字符,可以使用grep
(GNU grep 版本 3.4)命令如下:
$ echo x£β | grep -o '^.'
x
$ echo x£β | grep -o '^..'
x£
$ echo x£β | grep -o '^...'
x£β
在评论的帮助下,这个答案得到了改进。
答案2
在UTF-8编码中,的十六进制£
值为0xC2 0xA3 (c2a3)
二进制11000010 10100011
。
所以它是两个字节(就像两个字符)。cut -c
将每个字节视为一个产生的字符�
。
$ echo -n £ | xxd
00000000: c2a3 ..
$ echo -n £ | wc --bytes
2