spl*_*nux 4 binary bash shell awk hex
我的每一行都有一个十进制数file.txt:
1
2
3
Run Code Online (Sandbox Code Playgroud)
我正在尝试(现在已经太久了)编写一个单行脚本来生成一个输出,其中每一行都有一个带十进制,十六进制和二进制的列.为了简化任务,我们可以说原始数字以字节表示.所以最大值是255.
我首先尝试将每个数字解码为前缀为0的旁数,以便具有8位模式:
awk '{print "ibase=10;obase=2;" $1}' $1 | bc | xargs printf "%08d\n"
其中awk语句中的外部$ 1是file.txt.输出是:
00000001
00000010
00000011
Run Code Online (Sandbox Code Playgroud)十六进制相同,一个前置0
awk '{printf("0x%02x\n", $1)}' $1
和之前一样.输出是:
0x01
0x02
0x03
Run Code Online (Sandbox Code Playgroud)好吧,小数应该只是一个打印:
1
2
3
Run Code Online (Sandbox Code Playgroud)我想要的是我所拥有的一个班轮:
1 00000001 0x01
2 00000001 0x02
Run Code Online (Sandbox Code Playgroud)
所以基本上把1. 2.和3.放在输出的每一行.
我尝试使用system()在awk中执行bc(和其他命令)但没有成功.还有其他方式.你会这样做的方式是什么?
以下单行应该有效:
printf "%s %08d 0x%02x\n" "$1" $(bc <<< "ibase=10;obase=2;$1") "$1"
Run Code Online (Sandbox Code Playgroud)
示例输出:
$ 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
Run Code Online (Sandbox Code Playgroud)
因此,我寻找了一个简短而优雅的awk二进制转换器。不满意将其视为挑战,所以您来了。尺寸有所优化,所以我在下面放了一个可读的版本。
最后的printf指定数字应该多大。在这种情况下为8位。
这是错误的代码吗?嗯,是的。。。awk :-)当然不能处理非常大的数字。
AWK代码长67个字符:
awk '{r="";a=$1;while(a){r=((a%2)?"1":"0")r;a=int(a/2)}printf"%08d\n",r}'
Run Code Online (Sandbox Code Playgroud)
编辑:55个字符的awk代码
awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d\n",r}'
Run Code Online (Sandbox Code Playgroud)
可读版本:
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
}'
Run Code Online (Sandbox Code Playgroud)
然后问一个衬里有bin和hex
awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d 0x%02x\n",r,$1}'
Run Code Online (Sandbox Code Playgroud)
你不需要bc。这是仅使用 awk 的解决方案:
bits2str功能添加这个最小脚本:
{
printf("%s %s %x\n", $1, bits2str($1), $1)
}
Run Code Online (Sandbox Code Playgroud)这会产生:
$ awk -f awkscr.awk nums
1 00000001 1
2 00000010 2
3 00000011 3
Run Code Online (Sandbox Code Playgroud)