在AWK转换为十六进制或十进制的sed [英] Converting hex to decimal in awk or sed

查看:1729
本文介绍了在AWK转换为十六进制或十进制的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆