【发布时间】:2020-08-08 05:02:26
【问题描述】:
我正在使用 awk(符号链接到我的机器上的 gawk)来读取文件并获取每行的字符数来测试文件是否是固定宽度的。然后我可以通过-b --characters-as-bytes 选项重新使用以下脚本来查看文件是否按字节固定宽度。
#!/usr/bin/awk -f
BEGIN {
width = -1;
}
{
len = length($0);
if (width == -1) {
width = len;
} else if (len != 0 && len != width) {
exit 1;
}
}
我想做类似的事情来测试文件中的每一行是否具有相同数量的字节和字符,以假设所有字符都是一个字节(我确实意识到这是主题误报)。挑战是我想一次性浏览文件并在第一次不匹配时突破。有没有办法在 awk 脚本中设置 -b 选项,类似于如何调整 FS。如果这不可能,我愿意接受 awk 之外的选项。如果必须的话,我总是可以在C 写这个,但我想确保没有可用的东西。
效率是我的目标。拥有这些信息将帮助我跳过一个代价高昂的过程,因此我认为这本身并不昂贵。我正在处理可能超过 1 亿行的文件。
澄清
我想要类似上面的东西。像这样的
#!/usr/bin/awk -f
{
if (length($0) != bytelength($0))
exit 1;
}
我不需要任何输出。我将触发返回码(bash 中的$?)。因此,如果失败,请退出 1。显然 bytelength 不是一个函数。我只是在寻找一种无需运行两次 awk 即可实现此目的的方法。
更新
sundeep 的解决方案适用于我上面描述的内容:
awk -F '' -l ordchr '{for(i=1;i<=NF;i++) if(ord($i)<0) {exit 1;}}'
我的操作是假设awk 会将具有高于 0x7F 的 Windows 单字节编码的高端字符计算为单个字符,但实际上它根本不计算它。所以字节长度仍然与长度不同。我想我需要用 C 来写一些特定的东西。
结论
所以我认为我在解释我的问题方面做得很差。我收到以 UTF-8 或 Windows 风格的单字节编码(如 CP1252)编码的数据。我想检查文件中是否有任何多字节字符,如果找到则退出。我最初想在 awk 中执行此操作,但我使用可能具有不同编码的文件已被证明是困难的。
所以简而言之,如果我们假设一个文件中只有一个字符:
CHARACTER FILE_ENCODING ALL_SINGLE_BYTE IN_HEX
á UTF-8 false 0xC3 0xA1
á CP1252 true 0xE1
a ANY true 0x61
【问题讨论】:
标签: awk