有人知道可以将某些输出输送到bash
中,以匹配和转换所有出现十六进制数字并将所有其他文本匹配吗?
- 也许匹配相当任意的输出,这可能是十六进制应以某种方式转换为
/(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
的简短可行/可靠解决方案,所以我来这里寻求帮助。
使用e flag替换
perl -pe 's/(0x)?[0-9a-f]{5,}/hex $&/ge' file | column -t
带有autosplit Switch的perl:
perl -anE'say join " ", map {/(?:0x)?([0-9a-f]{5,})/i ? hex $1 : $_} @F' file | column -t
-n开关在文件的行上提供了隐式循环。
-e开关提供可选功能,例如say
Command (可用于自动运输返回的东西((。-e也做与执行参数中给出的代码的-e交换机(而不是寻找要启动的文件(。
-a开关(Autosplit(将每个线路上的每一行分开,并用零件填充@F
数组(就像Awk一样(。
map { } @F
处理@F
的每个元素并返回新数组。
/(?:0x)?([0-9a-f]{5,})/i ? hex($1) : $_
使用三元运算符condition ? true : false
。当模式匹配时,它返回转换的捕获组1,而不是原始部分。
请注意,Perl是一种考虑上下文的语言。$_
内部的map {}
是指@F
项目,/(?:0x)?([0-9a-f]{5,})/i
是$_ =~ /(?:0x)?([0-9a-f]{5,})/i
的简短版本。(map {}
$_
之外是当前行(
对不起。这是使用Bash的功能的单线:
cat /proc/net/stat/arp_cache | sed -e '2,$s/s*([0-9a-f][0-9a-f]*)s*/ $(( 0x1 )) /g' -e 's/^/echo /' | bash | 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
8 2 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 211 58 0 0 0 0 0 0 0
8 2 0 0 6319 1677 0 0 0 3882 0 0 0
8 4 0 0 4731 1299 0 0 0 0 0 0 0
带有 mawk
:对于每行,但第一行(NR!=1
(循环从第一列到最后一列( NF
(,然后将当前列($i
(从十位转换为十进制。
mawk 'NR!=1 {for (i=1; i<=NF; i++) $i=sprintf("%d ","0x"$i)}1' file | column -t
输出:
条目Allocs Destroys Hash_grows查找命中res_failed rcv_probes_mcast rcv_probes_ucast ofcect occed_gc_runs forced_gc_runs unresolved_discards table_fulls13 6 4 0 49696 49605 0 0 0 38201 0 0 0 0 013 13 4 1 0 0 0 0 0 0 0 1984 0 0 0 013 8 8 1 0 0 0 0 0 0 1752 0 0 013 10 8 0 0 0 2 0 0 1775 0 0 0 0
with 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 "%dn",strtonum("0x"$i)}}' filename
领先的 0
被认为是八进制,而领先的0x
被认为是十六进制。如果您的数字符合该标准,则$(( <number> ))
将将它们转换为十进制:
$ echo $(( 0x1b ))
27
$ echo $(( 014 ))
12