我有一个文件名x
$ cat x
1A34532112345
我想使用awk
我编写的脚本以十六进制打印(在网络的帮助下)
fold -1 /home/cscape/Desktop/x | gawk '{ printf("%s , %X\n",$0, int($0) )}'
但每个字符的输出是0
$ fold -1 /home/cscape/Desktop/x | gawk '{ printf("%s , %X\n",$0, int($0) )}'
1 , 1
A , 0
3 , 3
4 , 4
5 , 5
3 , 3
2 , 2
1 , 1
1 , 1
2 , 2
3 , 3
4 , 4
5 , 5
为什么。0
A
即使%d
。我想打印A
as的 ASCII 值HEX
。
答案1
如果你不这样做有要使用 awk,你可以看看od
(“八进制转储”):
$ echo 1A34532112345 | od -t x1
0000000 31 41 33 34 35 33 32 31 31 32 33 34 35 0a
0000016
答案2
awk 会默默地将字符串转换为数字。哪个数字?通过获取字符串的初始十进制数字(""
如果字符串为空或不以任何十进制数字开头,如 的情况,这可能只是"A"
)并将其转换为数字而获得的数字。""
被转换为0
.所以所有这些都将转换为0
:
- “0”
- “0文本”
- “文本”
- ””
awk 仅在需要数字时才以这种方式将字符串转换为数字。在 中"0text" + 1
,需要一个数字,因此结果将是1
。在 just plain 中"0text"
,不需要数字,因此不会发生转换。在 中printf("%d", "0text")
,又需要一个数字,因此字符串将被转换为数字。
您正在寻找的是一个ord
函数,它不是 awk 中的本机函数。这gawk 文档描述了如何在 awk 中编写这样的函数。
答案3
知道这是非常古老的,但突然出现在谷歌结果的顶部,所以万一你也找到了这里的路......
传递给 printf() 的值是“A”,而不是十六进制值,也不是可以使用 int($0) 转换的字符串形式。正如其他人已经指出的那样,类型转换在 awk 或同时代的其他语言中并不完全相同。
$ awk 'BEGIN{printf("%s, %X, %d\n", "A", "A", "A")}'
A, 0, 0
郑重声明,如果您不使用 Python 等现代语言所需的语法,那么它也没有什么不同:
>>> int("0xA")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '0xA'
>>> int("0xA", 16)
10
不过 awk 有一个简单的解决方案。只需添加前导“0x”即可将字符串“转换”为十六进制值,然后使用带有适当“%X”的 printf 进行打印。后者与将 base=16 传递给 python 中的 int() 函数没有什么不同 [awk 的 int() 不支持的技巧]。
$ awk 'BEGIN{printf("%s, %X, %d\n", "A", "0xA", "0xA")}'
A, A, 10
是的,它从输出中去除 0x。如果有疑问,请通过使用 sprintf 将 int 转换为十六进制字符串来仔细检查期望,然后查看在不使用 printf 的情况下如何打印该值。 x+1 产生“B”,证明 awk 将 x 视为数字,并且 sprintf 正在转换为十六进制,但只是不包括前导“0x”。我的意思是,如果一次构建一个 4 字节值两个字节,那会有多烦人。
$ awk 'BEGIN{x=10; y=sprintf("%X", x); print(y)}'
A
$ awk 'BEGIN{x=10; y=sprintf("%X", x+1); print(y)}'
B
此外,您可以在需要时随时添加它们。
$ awk 'BEGIN{x=10; y=sprintf("%X", x+1); printf("x = %d, x+1 = 0x%02X, x^3 = 0x%04X\n", x, x+1, x^3)}'
x = 10, x+1 = 0x0B, x^3 = 0x03E8
当然,这在 python 中也同样适用
>>> print("%04X 0x%04X\n" % (1000, 1000))
03E8 0x03E8
无论如何,简单地在 awk 中添加“0x”比 python 方式简单得多
>>> hex(int("A", 16))
'0xa'
说了这么多,最初的问题有点奇怪,因为原始文件已经包含一个不需要转换的十六进制值......除非有一些不言而喻的更大的需要重新格式化,而操作没有提到。