How to write binary data in Bash

Let's say there is a variable in the bash script with the value "001", how can I write this binary data to a file as bits (as "001", not "1") echo writes it as a string, but I want to write in bits.

+1


source to share


5 answers


You can write arbitrary bytes in hex or octal format with:

printf '\x03' > file   # Hex
printf '\003' > file   # Octal

      

If you have binary, this is a bit tricky, but you can turn it to octal with:

printf '%o\n' "$((2#00000011))"

      



which of course can be nested in the following:

binary=00000011
printf "\\$(printf '%o' "$((2#$binary))")" > file

      

Note that this only works with 8 bits. If you want to write longer values, you need to split them into groups of 8.

+4


source


Just use %b

in printf:

printf "%b" "\012"
printf "%b" "\x0a"

      

% b - print the associated argument when interpreting the backslash goes there

so above both printable characters is the binary value for the decimal 10

.

printf "%b" "\x0a" | od -bc

      



Output

0000000   012                                                            
          \n      

      

you can even mix

printf "%b" "\12\xa\n" | od -bc

0000000   012 012 012                                                    
          \n  \n  \n            

      

+3


source


More often than not, you want to write a template (like a 32 bit template).

# Write 32 bits 5 times to a file 
for i in {1..5}
do
   printf '\x12\x34\xAC\xCD' >> binaryfile.bin
done

      

Another example:

for i in {1..255}
do
    hx=$( printf "%x" $i )
    output="\x$hx\x00\x00\x00"
    printf "%b" $output >> binaryfile.bin 
done

      

+1


source


Using bc (on CentOS 7.4):

VALUE="3F"
INPUT_BASE=16
OUTPUT_BASE=2
printf "%b\n" $(bc <<< "ibase=$INPUT_BASE; obase=$OUTPUT_BASE; $VALUE")

      

RESULT : 111111

If leading zeros are needed then:

VALUE="3F"
INPUT_BASE=16
OUTPUT_BASE=2
printf "%16b\n" $(bc <<< "ibase=$INPUT_BASE; obase=$OUTPUT_BASE; $VALUE") | sed 's^ ^0^g'

      

RESULT : 0000000000111111

Note the use of 16 in printf format; change the value to limit the leading zero

0


source


A couple of more general functions for printing integers to a file:

le16 () { # little endian 16 bit;  1st param: integer to 2nd param: file 
  v='awk -v n=$1 'BEGIN{printf "%04X", n;}''
  echo -n -e "\\x${v:2:2}\\x${v:0:2}" >> $2
}

le32 () { # 32 bit version
  v='awk -v n=$1 'BEGIN{printf "%08X", n;}''
  echo -n -e "\\x${v:6:2}\\x${v:4:2}\\x${v:2:2}\\x${v:0:2}" >> $2
}

      

0


source







All Articles