Does anyone know of a oneliner into which some output can be piped into in bash, to match and convert all occurrences of hexadecimal numbers and leave all other text untouched?
/(0x)?[0-9a-fA-F]{5,}/ 0x shall not be neccessary, but
also be handled properly It should work on output like:
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
Most other questions on stackoverflow only tackle the issue of how to convert single numbers between number systems, only do the conversion for a specified column or completely kill the formatting being present in the input.
Desired output should look like: (column -t is there anyway, it really just need to replace the hex values it can find, and adding leading zeroes to a printf statement is also not a problem)
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
I could not find a short viable/reliable solution via sed/awk/perl in the last two hours, so I came here for help.
perl using e flag to substitution
perl -pe 's/(0x)?[0-9a-f]{5,}/hex $&/ge' file | column -t
perl with the autosplit switch:
perl -anE'say join " ", map {/(?:0x)?([0-9a-f]{5,})/i ? hex $1 : $_} @F' file | column -t
The -n switch provides an implicit loop over the lines of the file.
The -E switch makes available optional features like the say command (useful to print something with an automatic carriage return). -E does also the same thing that the -e switch that executes the code given in parameter (instead of looking for a file to launch).
The -a switch (autosplit) splits each line on whitespace and populates the @F array with the parts (like awk does).
map { } @F processes each elements of @F and returns a new array.
/(?:0x)?([0-9a-f]{5,})/i ? hex($1) : $_ uses the ternary operator condition ? true : false. When the pattern matches it returns the converted capture group 1, when it doesn't the original part.
Note that Perl is a language that takes account of the context. $_ inside the map {} refers to a @F item, and /(?:0x)?([0-9a-f]{5,})/i is the short version for $_ =~ /(?:0x)?([0-9a-f]{5,})/i. (outside of the map {} $_ is the current line)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With