我想打印前 1000 个人物在 UTF-8 编码的文件中。我知道头工具可以打印文件的前 n 个字节,但它可能会在中间剪切一个字符,因此最后会得到乱码输出。
我可以编写一个 awk 程序来执行此操作,但是否还有其他更简单的方法?
附言:我觉得不合理的是头和尾巴不支持字符编码(LANG 环境变量),而其他工具如切,厕所,sed和awk都支持字符编码。
答案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 上测试。