4

我在 a 的每一行都有一个十进制数file.txt

    1
    2
    3

我正在尝试(现在太久了)编写一个单行脚本来输出,其中每一行都有一个包含十进制、十六进制和二进制的列。为了简化任务,我们可以说原始数字以字节表示。所以最大值是255。

  1. 我首先尝试将每个数字解码为带有前缀 0 的二元数,以便具有 8 位模式:

    awk '{print "ibase=10;obase=2;" $1}' $1 | bc | xargs printf "%08d\n"

    awk 语句中的外部 $1 是file.txt. 输出是:

    00000001
    00000010
    00000011
    
  2. 与前面加一个 0 的十六进制相同

    awk '{printf("0x%02x\n", $1)}' $1

    和之前一样。输出是:

    0x01
    0x02
    0x03
    
  3. 好吧,小数点应该只是打印:

    1
    2
    3
    

我想要的是一个班轮,我有:

    1 00000001 0x01
    2 00000001 0x02

所以基本上将 1. 2. 和 3. 放在输出的每一行中。

我尝试使用 system() 在 awk 中执行 bc (和其他命令)但没有成功。还有无数其他方式。你会怎么做?

4

3 回答 3

8

以下单行应该工作:

printf "%s %08d 0x%02x\n" "$1" $(bc <<< "ibase=10;obase=2;$1") "$1"

示例输出:

$ for i in {1..10}; do printf "%s %08d 0x%02x\n" "$i" $(bc <<< "ibase=10;obase=2;$i") "$i"; done
1 00000001 0x01
2 00000010 0x02
3 00000011 0x03
4 00000100 0x04
5 00000101 0x05
6 00000110 0x06
7 00000111 0x07
8 00001000 0x08
9 00001001 0x09
10 00001010 0x0a
于 2013-09-18T11:03:21.920 回答
6

所以我搜索了一个简短而优雅的 awk 二进制转换器。不满意认为这是一个挑战,所以你来了。对大小进行了一点优化,所以我在下面放了一个可读的版本。

最后的 printf 指定了数字应该有多大。在这种情况下为 8 位。

这是坏代码吗?嗯,是的......这是 awk :-) 当然不适用于非常大的数字。

67 个字符长的 awk 代码:

awk '{r="";a=$1;while(a){r=((a%2)?"1":"0")r;a=int(a/2)}printf"%08d\n",r}'

编辑:55 个字符的 awk 代码

awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d\n",r}'

可读版本:

awk '{r=""                    # initialize result to empty (not 0)
      a=$1                    # get the number
      while(a!=0){            # as long as number still has a value
        r=((a%2)?"1":"0") r   # prepend the modulos2 to the result
        a=int(a/2)            # shift right (integer division by 2)
      }
      printf "%08d\n",r       # print result with fixed width
     }'

而被问到的一个带 bin 和 hex 的衬垫

awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d 0x%02x\n",r,$1}'
于 2015-08-12T13:09:21.310 回答
4

你不需要bc。这是仅使用 awk 的解决方案:

  • 获取手册中可用bits2str的功能
  • 添加这个最小的脚本:

    {
        printf("%s %s %x\n", $1, bits2str($1), $1)
    }
    

这会产生:

$ awk -f awkscr.awk nums 
1 00000001 1
2 00000010 2
3 00000011 3
于 2013-09-18T10:57:11.187 回答