sed - 在 awk 或 sed 中将十六进制转换为十进制

标签 sed awk decimal hex

我有一个数字列表,以逗号分隔:

123711184642,02,3583090366663629,639f02012437d4
123715942138,01,3538710295145500,639f02afd6c643
123711616258,02,3548370476972758,639f0200485732

我需要将第三列分成三列,如下所示:

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* ]] && 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
    }'

我采用了一种相当扭曲的方式来添加 --non-decimal-data如果需要的话可以选择。

编辑

只是为了好玩,这里是纯 Bash 的等价物:

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

"${line[*]:0:3}"(引用 *)的工作方式与 AWK 的 OFS 类似,因为它导致 Bash 的 IFS (此处为逗号)插入到输出的数组元素之间。我们可以通过插入数组元素来进一步利用该功能,如下所示,这与我上面的 AWK 版本更接近。

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

不幸的是,Bash 不允许 printf -v (类似于 sprintf())对数组元素进行赋值,因此 printf -v “line[6]”... 不起作用。

编辑:从 Bash 4.1 开始,printf -v 现在可以对数组元素进行赋值。示例:

printf -v 'line[6]' '%d' "0x${line[3]:10:4}"

需要在数组引用周围加上引号,以防止可能的文件名匹配。如果当前目录中存在名为“line6”的文件并且未引用引用,则将创建(或更新)包含 printf 输出的名为 line6 的变量。该文件的其他内容(例如其内容)不会发挥作用。只有名字——而且只是切线。

关于sed - 在 awk 或 sed 中将十六进制转换为十进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4614775/

相关文章:

linux - 如何使用awk找出某​​一行中的字段数?

Java 文本字段十进制验证

perl - 如何修剪文件 - 删除具有相同值的列

regex - sed 正则表达式提取字段并构建新的

linux - 如何使用 sed 复制十六进制格式的行?

linux - 是否可以将命令的输出添加到 linux 中的文本文件(而不是覆盖文本文件)?

bash - 比较两个文件并打印具有匹配列的行 awk

linux - 有没有办法将一些 "|"(不是全部)转换为 linux 文本文件中的逗号?

java - 使用 matcher() 匹配字符串中的小数

c# - 简化百分比计算c#