如何在bash中编写二进制数据

时间:2017-04-04 17:35:22

标签: bash shell

让我们说bash脚本中有一个值为“001”的变量如何将这个二进制数据写入文件中作为位(如“001”而非“1”)echo将其写为字符串但我想写在位。

6 个答案:

答案 0 :(得分:4)

您可以使用:

以十六进制或八进制写入任意字节
printf '\x03' > file   # Hex
printf '\003' > file   # Octal

如果你有二进制文件,它有点诡计,但你可以用以下方法将它变成八进制:

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

当然可以嵌套在上面:

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

请注意,这仅适用于最多8位。如果要编写更长的值,则必须将其拆分为8个组。

答案 1 :(得分:3)

只需使用printf中的%b

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

%b - 在解释反斜杠时打印关联的参数   在那里逃跑

所以,上面两个都打印十进制10的二进制值。

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

输出

0000000   012                                                            
          \n      

你甚至可以混合

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

0000000   012 012 012                                                    
          \n  \n  \n            

答案 2 :(得分:0)

使用 bc (在CentOS 7.4中):

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

结果:111111

如果需要前导零,则:

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

结果:0000000000111111

请注意在printf格式中使用16;更改值以限制前导零计数

答案 3 :(得分:0)

通常,您想编写一个模式(例如32位模式)。

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

另一个例子:

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

答案 4 :(得分:0)

一些用于将整数输出到文件的通用函数:

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
}

答案 5 :(得分:0)

我最近需要这个,有人可能会发现它有用:

#!/bin/bash

# generate bitmasks for a C array

# loop counter
NUMBER=0
MAX_BITMASK_LENGTH=8
# max loop value : 2^8 = 255
MAXVAL=$((2**MAX_BITMASK_LENGTH))
# line number
LINE=0

# echo start of C array
echo "    const long int bitmasks[${MAX_BITMASK_LENGTH}] = {"

# loop over range of values
while [ ${NUMBER} -le ${MAXVAL} ] ; do

    # use bc to convert to binary
    BINARY=`echo -e "obase=2\n${NUMBER}"| bc`

    # print current number, linenumber, binary
    printf "%12s, /* (%i) %8s */\n" ${NUMBER} ${LINE} ${BINARY}

    # increase loop value to next value
    NUMBER=$(((NUMBER*2)+1))

    # increment line number
    LINE=$((LINE+1))
done

# echo end of C array
echo "        };"

这将输出:

$ ./generate_bitmasks.sh
    const long int bitmasks[8] = {
           0, /* (0)        0 */
           1, /* (1)        1 */
           3, /* (2)       11 */
           7, /* (3)      111 */
          15, /* (4)     1111 */
          31, /* (5)    11111 */
          63, /* (6)   111111 */
         127, /* (7)  1111111 */
         255, /* (8) 11111111 */
        };