为了确保,是否真的使用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。
答案 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。
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 标准化,因此到目前为止这应该不是问题。