在AWK转换为十六进制或十进制的sed [英] Converting hex to decimal in awk or sed
问题描述
我有号码的列表,以逗号分隔:
123711184642,02,3583090366663629,639f02012437d4
123715942138,01,3538710295145500,639f02afd6c643
123711616258,02,3548370476972758,639f0200485732
我要第3列分成三个如下:
123711184642,02,3583090366663629,639f02,0124,37d4
123715942138,01,3538710295145500,639f02,afd6,C643
123711616258,02,3548370476972758,639f02,0048,5732
和转换位数的最后两列成十进制:
123711184642,02,3583090366663629,639f02,292,14292
123715942138,01,3538710295145500,639f02,45014,50755
123711616258,02,3548370476972758,639f02,72,22322
下面是对乔纳森的回答变化:
awk的$([$(AWK --version)= GNU *]]&放大器;&安培;回声--non十进制数据)-F
BEGIN {OFS = FS}
{
$ 6 = sprintf的(%d个,0XSUBSTR($ 4,11,4))
$ 5 =的sprintf(%d个,0XSUBSTR($ 4,7,4))
$ 4 = SUBSTR($ 4,1,6)
打印
}
我包括添加的一个相当扭曲的方式 - 如果它需要非十进制数据
选项
修改
只是它的挫折感,这里的纯猛砸等价的:
saveIFS = $ IFS
IFS =,
而读-r -a线
做
printf的'%S,%S,%D,%d个\\ N'$ {行[*] 0:3}$ {线[3]:0:6},0X $ {线[3] :6:4},0x的$ {线[3]:10:4}
DONE
IFS = $ saveIFS
的$ {行[*] 0:3}
(报价 *
)的作品相似AWK的 OFS
,它可使bash的 IFS
(这里是逗号)输出数组元素之间插入。我们可以通过插入数组元素如下一种更接近于平行我上面的AWK版本采取特征的又一优势。
saveIFS = $ IFS
IFS =,
而读-r -a线
做
行[6] = $(printf的'%D'0X $ {线[3]:10:4})
行[5] = $(printf的'%D'0X $ {线[3]:6:4})
行[4] = $(的printf'%s'的$ {线[3]:0:6})
printf的'%s的\\ n'$ {行[*]}
DONE
IFS = $ saveIFS
不幸的是,猛砸不允许的printf -v
(这类似于的sprintf()
),使分配给数组元素,因此的printf -v行[6]...
不起作用。
I have a list of numbers, comma-separated:
123711184642,02,3583090366663629,639f02012437d4
123715942138,01,3538710295145500,639f02afd6c643
123711616258,02,3548370476972758,639f0200485732
I need to split the 3rd column into three as below:
123711184642,02,3583090366663629,639f02,0124,37d4
123715942138,01,3538710295145500,639f02,afd6,c643
123711616258,02,3548370476972758,639f02,0048,5732
And convert the digits in the last two columns into decimal:
123711184642,02,3583090366663629,639f02,292,14292
123715942138,01,3538710295145500,639f02,45014,50755
123711616258,02,3548370476972758,639f02,72,22322
Here's a variation on Jonathan's answer:
awk $([[ $(awk --version) = GNU* ]] && echo --non-decimal-data) -F, '
BEGIN {OFS = FS}
{
$6 = sprintf("%d", "0x" substr($4, 11, 4))
$5 = sprintf("%d", "0x" substr($4, 7, 4))
$4 = substr($4, 1, 6)
print
}'
I included a rather contorted way of adding the --non-decimal-data
option if it's needed.
Edit
Just for the heck of it, here's the pure-Bash equivalent:
saveIFS=$IFS
IFS=,
while read -r -a line
do
printf '%s,%s,%d,%d\n' "${line[*]:0:3}" "${line[3]:0:6}" "0x${line[3]:6:4}" "0x${line[3]:10:4}"
done
IFS=$saveIFS
The "${line[*]:0:3}"
(quoted *
) works similarly to AWK's OFS
in that it causes Bash's IFS
(here a comma) to be inserted between array elements on output. We can take further advantage of that feature by inserting array elements as follows which more closely parallels my AWK version above.
saveIFS=$IFS
IFS=,
while read -r -a line
do
line[6]=$(printf '%d' "0x${line[3]:10:4}")
line[5]=$(printf '%d' "0x${line[3]:6:4}")
line[4]=$(printf '%s' "${line[3]:0:6}")
printf '%s\n' "${line[*]}"
done
IFS=$saveIFS
Unfortunately, Bash doesn't allow printf -v
(which is similar to sprintf()
) to make assignments to array elements, so printf -v "line[6]" ...
doesn't work.
这篇关于在AWK转换为十六进制或十进制的sed的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!