Pet*_*amm 19 command-line utf-8 cut-command
我正在开发一个 bash 脚本并提出了以下奇怪的行为!
$ echo £ |cut -c 1
?
Run Code Online (Sandbox Code Playgroud)
符号£传递给下一个命令,cut其过滤器仅选择一个字符。
当我修改cut命令中的过滤器以选择 2 个字符时,则£通过!
$ echo £ |cut -c 1-2
£
Run Code Online (Sandbox Code Playgroud)
不是一个严重的问题,我在脚本中有一个解决方法,但是为什么在选择£标志时 cut 命令中的过滤器需要 2 个位置而不是 1 个位置?
Fed*_*eli 43
cutUbuntu 中的命令不支持多字节字符。 对于此版本的命令,字符与字节相同cut。
井号 ( £) 是一个 UTF-8 字符,由两个字节 (c2和a3) 组成:
$ echo £ | od -t x1
0000000 c2 a3 0a
0000003
Run Code Online (Sandbox Code Playgroud)
注:该0a字符为“换行符”(ASCII“换行符”字符)。
当您cut选择该行的第一个字符时,您只选择了 的c2一部分£,这不是有效的 UTF-8 字符。结果你会在屏幕上看到奇怪的问号?(替换字符):
$ echo £ | cut -c 1 | od -t x1
0000000 c2 0a
0000002
Run Code Online (Sandbox Code Playgroud)
注意:以上是在最新版本的cutUbuntu 20.10(GNU coreutils 版本 8.32)上测试的。
如果要选择多字节字符,可以使用grep(GNU grep version 3.4)命令,如下所示:
$ echo x£? | grep -o '^.'
x
$ echo x£? | grep -o '^..'
x£
$ echo x£? | grep -o '^...'
x£?
Run Code Online (Sandbox Code Playgroud)
在评论的帮助下,这个答案得到了改进。
Rav*_*ina 18
在 UTF-8 编码中,£is的十六进制值0xC2 0xA3 (c2a3)是11000010 10100011二进制的。
所以它是两个字节(就像两个字符)。cut -c将每个字节视为产生?.
$ echo -n £ | xxd
00000000: c2a3 ..
$ echo -n £ | wc --bytes
2
Run Code Online (Sandbox Code Playgroud)