使用 awk 以十六进制打印文件

使用 awk 以十六进制打印文件

我有一个文件名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

为什么。0A即使%d。我想打印Aas的 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'

说了这么多,最初的问题有点奇怪,因为原始文件已经包含一个不需要转换的十六进制值......除非有一些不言而喻的更大的需要重新格式化,而操作没有提到。

相关内容