我正在尝试使用 awk,我认为编写一个小程序将每个 ASCII 字符与其十六进制代码映射是一个很酷的主意。这就是我到目前为止所做的:
该字符串是:
abshdfitiggwigiwjirjgiejrigjr
我保持简单,不包括回车或制表符等
我将其转储到一个用逗号分隔的文件中,以便我可以使用 awk 的 -F 标志将它们识别为字段:
a,b,s,h,d,f,i,t,i,g,g,w,i,g,i,w,j,i,r,j,g,i,e,j,r,i,g,j,r,
我对同一文件的十六进制转储做了同样的事情:
61,62,73,68,64,66,69,74,69,67,67,77,69,67,69,77,6a,69,72,6a,67,69,65,6a,72,69,67,6a,72,0a,
我现在想,因为它们都有相同的 NF,所以会更容易,所以我尝试了以下 awk 命令:
awk -F ',' '{for(i=1;i<NF;i++){sum[$i]=$i}} END {for(char in sum) { print char, sum[char]} } ' line.txt linebits.txt
其中 line.txt 和 linebits.txt 对应于正确的文件
输出如下:
62 62
h h
72 72
i i
0a 0a
64 64
73 73
j j
w w
65 65
74 74
66 66
67 67
77 77
68 68
a a
69 69
b b
6a 6a
d d
e e
r r
f f
s s
61 61
g g
t t
这当然是有道理的,因为 sum[$i]=$i 只是在做 sum[g]=g ,并且我打印的两者是相同的
我知道为什么它显示这个输出,但我不知道如何修复它。
是否可以指定我想要哪个文件?是否可以获取标准输入的索引?我知道这听起来很疯狂哈哈
我想要的输出是:
char - hex code
char - hex code
.....
听起来您的目标是学习(关于)awk,而不是简单地获取 ASCII 表,而其他答案很容易获得该表。
为此,您不需要任何输入文件;您可以直接显示所有可打印字符
(这会生成一长列,就像您的尝试一样;如果您想要多列,则将其作为练习。)
OTOH,如果您想组合两行中的字段对 - 可以是任何值,而不仅仅是字符及其十六进制:
无论这两行来自两个文件(如您的情况)还是来自一个文件,这都有效。如果您有两行以上,则会将第 1 行到每个后续行的字段配对,这种模式对于 CSV 类型文件通常有意义,这些文件在第 1 行上有一个标题,其中包含每列的名称,后跟可变数量的行每列中都有数据。
这也保留了包括任何欺骗在内的顺序。为了消除欺骗但保持秩序:
如果你真的想要由此创建的随机顺序
for in
也是可能的,但这对我来说没有意义。一些有用的顺序,例如数字顺序或字母顺序(消除了重复)可能是有意义的。您已经获得了更简单的方法,但由于这里的目标似乎是学习 awk,因此我将如何使用您描述的方法来做到这一点。首先,我不会使用
,
分离,使用线条来完成类似的事情会更容易。然后我们可以使用NR
和FNR
特殊变量来连接这两个文件。NR
保存当前输入行号,同时保存当前正在读取的文件的FNR
输入行号。因此,如果我们给出两个文件,每个文件有 2 行,那么将从 到,但在读取第二个文件的第一行时,将从到然后回到,然后。awk
NR
1
4
FNR
1
2
1
2
把它们放在一起,我们可以做到:
有了这些文件,我们可以执行以下操作:
当然,这也可以使用 来完成
paste
,但没关系:为什么不使用现有的程序而不编写自己的程序呢?我建议
ascii
埃里克·S·雷蒙德(Eric S. Raymond)。要使用上述命令输出 ASCII 字符的十六进制值,请执行以下命令:
ascii -x
.输出示例:
如果您使用 GNU
awk
,那么您可以包含扩展库ordchr
:ord()
-函数,将 char 转换为十进制printf "%x", ord($i)
-将十进制转换为十六进制另外:
chr()
-将十进制转换为 char