linux - awk命令将十六进制转换为带符号的十进制

标签 linux bash shell awk text-editor

我有一个包含 3 列十六进制数字的文本文件(值是可变的,这些仅用作示例):

X     Y     Z
0a0a  0b0b  0c0c
0a0a  0b0b  0c0c
0a0a  0b0b  0c0c
0a0a  0b0b  0c0c

我想将这些数字转换为带符号的十进制数并以它们所在的相同结构打印它们,所以我这样做了:

awk '{x="0x"$1;
      y="0x"$2;
      z="0x"$3;
      printf ("%d %d %d" x,y,z);}' input_file.txt > output_file.txt

我作为输出获得的列表仅包含无符号值。

最佳答案

您可以使用 awk 函数进行二进制补码的转换:

function hex2int( hexstr, nbits )
{
    max = 2 ^ nbits
    med = max / 2

    num = strtonum( "0x" hexstr )

    return ((num < med) ? num : ( (num > med) ? num - max  :  -med ))
}

4bit 转换示例:

print hex2int( "7", 4 ) # +7
print hex2int( "2", 4 ) # +2
print hex2int( "1", 4 ) # +1
print hex2int( "0", 4 ) # 0
print hex2int( "f", 4 ) # -1
print hex2int( "d", 4 ) # -3
print hex2int( "9", 4 ) # -7
print hex2int( "8", 4 ) # -8

8bit 转换示例:

print hex2int( "7f", 8 ) # +127
print hex2int( "40", 8 ) # +64
print hex2int( "01", 8 ) # +1
print hex2int( "00", 8 ) # 0
print hex2int( "ff", 8 ) # -1
print hex2int( "40", 8 ) # -64
print hex2int( "81", 8 ) # -127
print hex2int( "80", 8 ) # -128

使用 16bit 转换将所有内容放在一起:

#!/bin/awk

function hex2int( hex )
{
    num = strtonum( "0x" hex )

    return ((num < med) ? num : ( (num > med) ? num - max  :  -med ))
}

BEGIN {
    nbits = 16
    max = 2 ^ nbits
    med = max / 2
}

{
    for( i = 1; i <= NF; i++ )
    {
        if( NR == 1 )
        {
            printf "%s%s", $i, OFS
        }
        else
        {
            printf "%d%s", hex2int($i), OFS
        }
    }

    printf "%s", ORS
}

# eof #

输入文件:

X     Y     Z
0a0a  0b0b  0c0c
abcd  ef01  1234
ffff  fafa  baba
12ab  abca  4321

测试:

$ awk -f script.awk -- input.txt 

输出:

X Y Z 
2570 2827 3084 
-21555 -4351 4660 
-1 -1286 -17734 
4779 -21558 17185 

引用: https://en.wikipedia.org/wiki/Two's_complement

希望对您有所帮助!

关于linux - awk命令将十六进制转换为带符号的十进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39655369/

相关文章:

function - 在 C-Shell 中的 .cshrc 中添加函数

swift - 如何使用 Swift 从 cocoa 应用程序运行 shell 脚本?

ruby - 由于 gpg 错误,无法在 Ubuntu 16.04 上安装 Ruby rvm

Android:在启动时挂载不同的用户数据分区

linux - linux cat 命令可以用于将文本写入文件吗?

linux - 确定 Web 服务器的根文件夹

linux - 在 sed/awk/grep 中将日期从 2012-01-31 更改为 31-01-2012

asp.net - asp.net中的命令提示符和asp中的执行文件

php - 使用 PHP 在外部服务器中运行应用程序

regex - grep 多个模式单文件参数列表太长