假设在Bash脚本中有一个取值为“001”的变量,如何将这个二进制数据以01位的形式写入文件(如“001”而不是“1”)?
echo
会将其作为字符串输出,但我想以比特位的形式输出。
你可以使用以下方式以十六进制或八进制编写任意字节:
printf '\x03' > file # Hex
printf '\003' > file # Octal
如果你有二进制,那就比较棘手,但是你可以使用以下方法将其转换为八进制:
$ echo 'obase=8; ibase=2; 101010' | bc 52
printf '%o\n' "$((2#00000011))"
当然,上面的内容可以嵌套使用:
binary=00000011
printf "\\$(printf '%o' "$((2#$binary))")" > file
请注意,这仅适用于最多8位。如果您想写更长的值,则必须将其分成8组。
\xFF
与\377
。您可以使用任何一个您喜欢的来工作。 - that other guy只需在 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
以下是用于将整数输出到文件的一些更通用的函数:
Original Answer翻译成"最初的回答"
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
}
v=$(printf "%04X" "$1")
- S-tracev=$(printf "%04X" "$1")
- undefined使用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;更改该值以限制前导零的数量
通常情况下,您需要编写一个模式(例如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
最近我需要这个,希望有人会发现它很有用:
#!/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 */
};
\x00
的情况下才有效,因为这个值不能作为参数表示。printf '\x00'
可以工作,因为它避免了直接传递二进制数据。 - that other guy