用于输出 UTF-8 编码文件中前 n 个字符的 Unix 工具

用于输出 UTF-8 编码文件中前 n 个字符的 Unix 工具

我想打印前 1000 个人物在 UTF-8 编码的文件中。我知道工具可以打印文件的前 n 个字节,但它可能会在中间剪切一个字符,因此最后会得到乱码输出。

我可以编写一个 awk 程序来执行此操作,但是否还有其他更简单的方法?

附言:我觉得不合理的是尾巴不支持字符编码(LANG 环境变量),而其他工具如厕所sedawk都支持字符编码。

答案1

不确定是否更简单,但这是我的方法:

cat file | iconv -t UTF-32 | head -c $[1000 *4+4] | iconv -f UTF-32

这会转换为固定宽度的 Unicode 形式,因此 1000 始终代表整个字符。

答案2

为了awk向其他 Google 员工提供 OP 提到的方法,我们用 5 进行测试尖音重读元音

printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'

选择前三个字符并输出所需的:

áéí

每个 UTF-8 字符都是 2 个字节长,我们可以这样检查:

printf 'áéíóú' | hd

这使:

00000000  c3 a1 c3 a9 c3 ad c3 b3  c3 ba                    |..........|
0000000a

因此我们可以等效地测试它:

printf '\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'

如果我们使用了错误的语言环境,例如C分别处理每个字节:

printf 'áéíóú' | LC_CTYPE=C awk '{print substr($0,1,3);exit}' | hd

给出前三个字节:

c3 a1 c3

终端上显示的内容如下:

á

因为它c3本身就是垃圾。

不确定iconv在处理大量输入时其性能如何。但对于小东西来说,这已经足够好而且简单了。

在 Ubuntu 21.04 上测试。

相关内容