bash:oneliner将输出中的十六进制数转换为小数

时间:2017-06-04 14:51:32

标签: regex bash hex decimal converter

是否有人知道某个输出可以在bash中输入到哪个oneliner,以匹配和转换所有出现的十六进制数字并保持所有其他文本不变?

  • 可能匹配相当任意的输出,可能是十六进制 应以某种方式通过正则表达式转换,即 /(0x)?[0-9a-fA-F]{5,}/
  • 领导0x不是必需的,但是 也可以妥善处理
  • 如果不是,可能会出现误报 指定数字的最小长度,但不应该是 问题
  • 目标是找到可以与尽可能多的输出一起使用的解决方案

它应该适用于输出:

ssg sjas # cat /proc/net/stat/arp_cache | column -t 
entries   allocs    destroys  hash_grows  lookups   hits      res_failed  rcv_probes_mcast  rcv_probes_ucast  periodic_gc_runs  forced_gc_runs  unresolved_discards  table_fulls
0000000d  00000006  00000004  00000000    0000c3b9  0000c35e  00000000    00000000          00000000          0000965b          00000000        00000000             00000000
0000000d  0000000d  00000004  00000001    00000000  00000000  00000000    00000000          00000000          000007cd          00000000        00000000             00000000
0000000d  00000008  00000008  00000001    00000000  00000000  00000000    00000000          00000000          000006e0          00000000        00000000             00000000
0000000d  0000000a  00000008  00000000    00000000  00000000  00000002    00000000          00000000          00000704          00000000        00000000             00000000

stackoverflow上的大多数其他问题仅解决了如何在数字系统之间转换单个数字的问题,仅针对指定列进行转换或完全终止输入中存在的格式。

所需的输出应该如下所示:( column -t无论如何,它实际上只需要替换它可以找到的十六进制值,并且将前导零添加到printf语句也不是问题)

ssg sjas # cat /proc/net/stat/arp_cache | perl -pe 's/(?:0x)?[0-9a-f]{5,}/hex($&)/ge' | column -t
entries  allocs  destroys  hash_grows  lookups  hits   res_failed  rcv_probes_mcast  rcv_probes_ucast  periodic_gc_runs  forced_gc_runs  unresolved_discards  table_fulls
13       6       4         0           50105    50014  0           0                 0                 38491             0               0                    0
13       13      4         1           0        0      0           0                 0                 1997              0               0                    0
13       8       8         1           0        0      0           0                 0                 1760              0               0                    0
13       10      8         0           0        0      2           0                 0                 1796              0               0                    0

在过去的两个小时里,我无法通过sed / awk / perl找到一个简短可行/可靠的解决方案,所以我来到这里寻求帮助。

6 个答案:

答案 0 :(得分:4)

perl使用e标志替换

perl -pe 's/(0x)?[0-9a-f]{5,}/hex $&/ge' file | column -t

答案 1 :(得分:2)

perl with autosplit switch:

SELECT
    S.SaleItemID,
    Format(SUM(R.RecItemQty), "###,##0.00")AS 'Received'
    Format(SUM(S.SaleItemQty), "###,##0.00")AS 'Quantity',
    Format(SUM(S.SaleItemPrice), "###,##0.00")AS 'Amount',
    S.SaleItemDate
 FROM Items_Sales S
 INNER JOIN Items_Rec R
    ON S.SaleItemID = R.RecItemID
    AND S.SalesItemDate = R.RecItemDate
 GROUP BY S.SaleItemID,S.SaleItemDate

-n开关在文件的行上提供隐式循环。

-E开关提供可选功能,例如perl -anE'say join " ", map {/(?:0x)?([0-9a-f]{5,})/i ? hex $1 : $_} @F' file | column -t 命令(用于打印带有自动回车的内容)。 -E也与执行参数中给出的代码的-e开关相同(而不是查找要启动的文件)。

-a开关(autosplit)在空白处拆分每一行,并用部分填充say数组(如awk一样)。

@F处理map { } @F的每个元素并返回一个新数组。

@F使用三元运算符/(?:0x)?([0-9a-f]{5,})/i ? hex($1) : $_。当模式匹配时,它返回转换后的捕获组1,而不是原始部分。

请注意,Perl是一种考虑上下文的​​语言。 condition ? true : false内的$_引用map {}项,@F/(?:0x)?([0-9a-f]{5,})/i的简短版本。 $_ =~ /(?:0x)?([0-9a-f]{5,})/i map {}之外是当前行)

答案 2 :(得分:1)

使用mawk:对于每一行但第一行(NR!=1)从第一列到最后一列(NF)循环并将当前列($i)从十六进制转换为小数。

mawk 'NR!=1 {for (i=1; i<=NF; i++) $i=sprintf("%d ","0x"$i)}1' file | column -t

输出:

entries  allocs  destroys  hash_grows  lookups  hits   res_failed  rcv_probes_mcast  rcv_probes_ucast  periodic_gc_runs  forced_gc_runs  unresolved_discards  table_fulls
13       6       4         0           49696    49605  0           0                 0                 38201             0               0                    0
13       13      4         1           0        0      0           0                 0                 1984              0               0                    0
13       8       8         1           0        0      0           0                 0                 1752              0               0                    0
13       10      8         0           0        0      2           0                 0                 1775              0               0                    0

答案 3 :(得分:1)

很抱歉这个混乱。这是一个使用bash功能的单行:

public class ColorPicker extends View {

    public ColorPicker(Context context, AttributeSet attrs) {
        super(context, attrs);    
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();    
        // call getParent() here
    }
}

答案 4 :(得分:0)

GNU awk

awk 'BEGIN{IFS=OFS="\t"}NR==1{print $0}{for(i=1;i<=NF;i++) if(i!=NF){printf "%s%c",strtonum("0x"$i),OFS}else{printf "%d\n",strtonum("0x"$i)}}' filename

答案 5 :(得分:-1)

前导0被视为八进制,前导0x被视为十六进制。如果您的号码符合该标准,那么$(( <number> ))会将它们转换为十进制:

$ echo $(( 0x1b ))
27
$ echo $(( 014 ))
12