Convert decimal to hexadecimal and binary in shell script

I have a decimal number in each line of file.txt :

  1 2 3 

I am trying (too long) to write a single line script to have output where each row has a column with decimal, hexadecimal and binary. To facilitate the task, we can say that the original number is expressed in bytes. Thus, the maximum value is 255.

  • First, I try to decode each number as a binar with 0 added in order to have an 8-bit pattern:

    awk '{print "ibase=10;obase=2;" $1}' $1 | bc | xargs printf "%08d\n"

    where the outer $ 1 in the awk statement is file.txt . Exit:

     00000001 00000010 00000011 
  • Same thing for hex with one 0 added

    awk '{printf("0x%02x\n", $1)}' $1

    Same as before. Exit:

     0x01 0x02 0x03 
  • Well, the decimal value should just be a print:

     1 2 3 

I would like to have one liner where I have:

  1 00000001 0x01 2 00000001 0x02 

therefore basically put 1. 2. and 3. in each line of output.

I tried to execute the bc command (and another command) in awk using system () with no success. And millions more other ways. How do you do this?

+4
source share
3 answers

The following working liner should work:

 printf "%s %08d 0x%02x\n" "$1" $(bc <<< "ibase=10;obase=2;$1") "$1" 

Output Example:

 $ for i in {1..10}; do printf "%s %08d 0x%02x\n" "$i" $(bc <<< "ibase=10;obase=2;$i") "$i"; done 1 00000001 0x01 2 00000010 0x02 3 00000011 0x03 4 00000100 0x04 5 00000101 0x05 6 00000110 0x06 7 00000111 0x07 8 00001000 0x08 9 00001001 0x09 10 00001010 0x0a 
+7
source

You do not need bc . Here's a solution using only awk:

  • Get bits2str function available in the manual
  • Add this minimal script:

     { printf("%s %s %x\n", $1, bits2str($1), $1) } 

This gives:

 $ awk -f awkscr.awk nums 1 00000001 1 2 00000010 2 3 00000011 3 
+4
source

So, I was looking for a short and elegant binary awk converter. Not satisfied saw this as a challenge, so you are here. Slightly optimized for size, so I posted a readable version below.

The end of printf indicates how large the numbers should be. In this case, 8 bits.

Is this bad code? Hmm, yes ... this is awk :-) Of course, it does not work with very large numbers.

Awk code length 67 characters:

 awk '{r="";a=$1;while(a){r=((a%2)?"1":"0")r;a=int(a/2)}printf"%08d\n",r}' 

Edit: 55 characters awk code

 awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d\n",r}' 

Readable Version:

 awk '{r="" # initialize result to empty (not 0) a=$1 # get the number while(a!=0){ # as long as number still has a value r=((a%2)?"1":"0") r # prepend the modulos2 to the result a=int(a/2) # shift right (integer division by 2) } printf "%08d\n",r # print result with fixed width }' 

And asked one liner with bin and hex

 awk '{r="";a=$1;while(a){r=a%2r;a=int(a/2)}printf"%08d 0x%02x\n",r,$1}' 
+4
source

Source: https://habr.com/ru/post/1502787/


All Articles