不使用gawk的bash中十六进制到十进制转换

时间:2018-10-11 02:19:14

标签: bash awk

输入:

cat test1.out
12 ,         maze|style=0x48570006, column area #=0x7, location=0x80000d
13 ,         maze|style=0x48570005, column area #=0x7, location=0x80aa0d
....
...
..
.

所需的输出:

12 ,         maze|style=0x48570006, column area #=0x7, location=8388621   <<<8388621 is decimal of 0x80000d
....

我只想将最后一列转换为十进制。 我无法使用gawk,因为我们公司的机器中到处都没有它。 尝试使用awk --non-decimal-data,但是它也没有用。 想知道 printf 命令是否可以将最后一个单词从十六进制翻转为十进制。 您还有其他建议吗?

7 个答案:

答案 0 :(得分:3)

这里不需要awk或任何其他外部命令:bash的本机数学运算在算术上下文中可以正确处理十六进制值(这就是echo $((0xff))发出255的原因)。

#!/usr/bin/env bash
#              ^^^^- must be really bash, not /bin/sh

location_re='location=(0x[[:xdigit:]]+)([[:space:]]|$)'

while read -r line; do
  if [[ $line =~ $location_re ]]; then
    hex=${BASH_REMATCH[1]}
    dec=$(( $hex ))
    printf '%s\n' "${line/location=$hex/location=$dec}"
  else
    printf '%s\n' "$line"
  fi
done

您可以在https://ideone.com/uN7qNY上看到它运行

答案 1 :(得分:1)

等等,难道您不能仅在其他aks中使用printf吗?它不能与gawk一起使用,但可以与其他awks一起使用,对吗?例如,使用mawk:

$ mawk 'BEGIN{FS=OFS="="}{$NF=sprintf("%d", $NF);print}' file
12 ,         maze|style=0x48570006, column area #=0x7, location=8388621
13 ,         maze|style=0x48570005, column area #=0x7, location=8432141

我用mawk,awk-20070501,awk-20121220和Busybox awk进行了测试。

在编辑后被丢弃,但出于评论的考虑而保留:

使用revcut提取最后的=printf进行hex2dec转换:

$ while IFS='' read -r line || [[ -n "$line" ]] 
  do 
      printf "%s=%d\n" "$(echo "$line" | rev | cut -d = -f 2- | rev)" \
                        $(echo "$line" | rev | cut -d = -f 1 | rev) 
  done < file

输出:

12 ,         maze|style=0x48570006, column area #=0x7, location=8388621
13 ,         maze|style=0x48570005, column area #=0x7, location=8432141

答案 2 :(得分:1)

考虑到case strtonum()函数不可用的情况,怎么办:

#!/bin/bash

awk -F'location=0x' '

function hex2dec(str,
    i, x, c, tab) {
    for (i = 0; i <= 15; i++) {
            tab[substr("0123456789ABCDEF", i + 1, 1)] = i;
    }
    x = 0
    for (i = 1; i <= length(str); i++) {
            c = toupper(substr(str, i, 1))
            x = x * 16 + tab[c]
    }
    return x
}

{
    print $1 "location=" hex2dec($2)
}
' test1.out

其中hex2dec()是strtonum()的自制替代物。

答案 3 :(得分:1)

如果您安装了Perl,那么没有Gawk就显得无关紧要了。

perl -pe 's/location=\K0x([0-9a-f]+)/ hex($1) /e' file

答案 4 :(得分:0)

这可能对您有用(GNU sed和Bash):

sed 's/\(.*location=\)\(0x[0-9a-f]\+\)/echo "\1$((\2))"/Ie' file

使用模式匹配和向后引用来拆分每行,然后评估echo命令。

替代:

sed 's/\(.*location=\)\(0x[0-9a-f]\+\)/echo "\1$((\2))"/I' file | sh

答案 5 :(得分:0)

BASH_REMATCH 数组信息:

http://molk.ch/tips/gnu/bash/rematch.html

精髓:

let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = eligibleArray[indexPath.row]
cell.layoutMargins = .zero
cell.separatorInset = .zero
cell.textLabel?.textColor = .secondaryLabel
cell.textLabel?.backgroundColor = .systemOrange
cell.textLabel?.numberOfLines = 0
cell.backgroundColor = .systemPink

如果 'string' 匹配 'regexp',

.. 字符串的匹配部分存储在 BASH_REMATCH 数组中。

[[ string =~ regexp ]]

[[ "abcdef" =~ (b)(.)(d)e ]]

享受吧!

答案 6 :(得分:0)

Bash 的原生数学运算可以随时正确处理十六进制值。

示例:

echo $(( 0xff))

255


printf '%d' 0xf0

240
相关问题