关于awk和整数到ASCII字符的转换

时间:2016-12-27 21:51:43

标签: awk gawk

为了确保,是否真的使用awk(至少是Gnu awk)我可以转换:

从八进制到ASCII由:

print "\101"         # or a="\101"
A

从十六进制到ASCII:

print "\x41"         # or b="\x41"
B

但是从十进制到ASCII我必须:

$ printf "%c\n", 67  # or c=sprintf("%c", 67)
C

我错过了RTFM(备忘录)中没有秘密print "\?67"

我试图从$0="aabccc"获取字符频率,如:

for(i=141; i<143; i++) a=a gsub("\\"i, ""); print a
213

但使用小数(而不是上例中的八进制)。十进制方法看起来非常长:

$ cat foo
aabccc
$ awk '{for(i=97;i<=99;i++){c=sprintf("%c",i);a=a gsub(c,"")} print a}' foo
213

使用了here

4 个答案:

答案 0 :(得分:2)

不,\nnn是八进制,\xnn是十六进制 - 这就是包含你不能在字符串中包含的字符的所有内容,你应该总是使用八进制而不是十六进制表示稳健性(例如,参见http://awk.freeshell.org/PrintASingleQuote)。

我不明白你问题的最后一部分你在说明你想要做什么 - 提供简洁,可测试的样本输入和预期输出,我相信有人可以帮助你以正确的方式做到这一点不管它是什么。

这是你想要做的吗?

$ awk 'BEGIN{for (i=0141; i<0143; i++) print i}'
97
98

答案 1 :(得分:1)

查找表是解决这个问题的唯一方法(直接将CHAR转换为ASCII DECIMAL)在&#34;仅限AWK&#34;。

您只需使用sprintf()将ASCII DECIMAL转换为CHAR。

  • 您可以通过迭代每个已知的查找表来创建查找表 ascii chars并将它们存储在一个数组中,其中键是字符,值是该char的ascii值。

  • 您可以在AWK中使用sprintf()来获取每个小数的字符。

  • 然后你可以将char传递给数组以获得相应的 十进制。

在此示例中,使用awk。

  • 我们遍历所有256个字符,打印出每个字符。
  • 我们将结果字符串拆分为一系列行,其中每行都有一个字符。
  • 我们用256个字符的awk(在BEGIN中)构建一个表,然后输入每个输入字符以查找每个字符。
  • 最后,我们打印出输入中每个字符的代码。
awk 'BEGIN{
    for(n=0;n<256;n++)
        print sprintf("%c",n)
}' | awk '{
for (i=0; ++i <= length($0);)
    printf "%s\n", substr($0, i, 1)
}' | awk 'BEGIN{
    for(n=0;n<256;n++)
        ord[sprintf("%c",n)]=n
}{
    print ord[$1]
}'

反过来也可以,我们查找字符代码列表。

awk 'BEGIN{
    for(n=0;n<256;n++)
        print sprintf("%s",n)
}' | awk 'BEGIN{
    for(n=0;n<256;n++)
        char[n]=sprintf("%c",n)
}{
    print char[$1]
}'

注意:第二个示例可能会在高ascii范围(> 128)中打印出大量垃圾,具体取决于您使用的字符集。

答案 2 :(得分:1)

如果正如你在问题的最后说的那样,你只是想计算字符的频率,我只是组装一个数组。

$ awk '{for(i=1;i<=length($0);i++) a[substr($0,i,1)]++} END{for(i in a) printf "%d %s\n",a[i],i}' <<<$'aabccc\ndaae'
1 d
1 e
4 a
1 b
3 c

请注意,这也支持多行输入。

我们逐步浏览每一行输入,递增一个计数器,该计数器是一个以相关字符键入的数组下标。

我希望这种方法比应用正则表达式计算每个有趣角色的替换更高效,但我还没有进行任何速度比较测试(当然这取决于你有多大的集合)感兴趣)。

虽然这个答案没有解决您的初步问题,但我希望它能提供更好的方法来解决问题。

(感谢您在问题中加入最后的详细信息。XY problems在这里非常频繁。)

答案 3 :(得分:0)

注意:根据您使用的字符集,第二个示例可能会在高 ascii 范围 (> 128) 中打印出大量垃圾。

这可以通过对 128-255 使用八进制代码 \200 - \377 来规避。

IIRC 字节 C0 C1 F5 F6 F7 F8 F9 FA FB FC FD FE FF 不应存在于正确编码的 UTF-8 文档中(或尚未指定)。 FE 和 FF 可能与 UTF16 字节顺序标记重叠,但由于世界已将 UTF-8 标准化,因此到目前为止这应该不是问题。