我想编写一个Bash程序,可以读取文件,比如*.bin文件,并打印出其中所有的十六进制数,就像“hex”编辑器一样。我应该从哪里开始?
od
命令:od -t x1 filename
示例输出:
$ printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -t x1
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66
*
0000040 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000060
od
是一个 Linux 程序还是一个 bash 函数?抱歉,我是一个真正的初学者。 - Nathan Camposwhich od
命令查看,如果你得到一个程序的名称,那么它就是一个外部程序(对于 od
命令来说,它很可能是这样的)。 - Greg Hewgillln -s bash-hexdump bash-hexdump-stream
,并作为./bash-hexdump-stream
运行),它将输出表示文件内容的连续十六进制字符流。否则,它的输出将类似于hexdump -C
。#!/bin/bash
# bash-hexdump
# by Dennis Williamson - 2010-01-04
# in response to https://dev59.com/YnI-5IYBdhLWcg3wI0p9
# usage: bash-hexdump file
if [[ -z "$1" ]]
then
exec 3<&0 # read stdin
[[ -p /dev/stdin ]] || tty="yes" # no pipe
else
exec 3<"$1" # read file
fi
# if the script name contains "stream" then output will be continuous hex digits
# like hexdump -ve '1/1 "%.2x"'
[[ $0 =~ stream ]] && nostream=false || nostream=true
saveIFS="$IFS"
IFS="" # disables interpretation of \t, \n and space
saveLANG="$LANG"
LANG=C # allows characters > 0x7F
bytecount=0
valcount=0
$nostream && printf "%08x " $bytecount
while read -s -u 3 -d '' -r -n 1 char # -d '' allows newlines, -r allows \
do
((bytecount++))
printf -v val "%02x" "'$char" # see below for the ' trick
[[ "$tty" == "yes" && "$val" == "04" ]] && break # exit on ^D
echo -n "$val"
$nostream && echo -n " "
((valcount++))
if [[ "$val" < 20 || "$val" > 7e ]]
then
string+="." # show unprintable characters as a dot
else
string+=$char
fi
if $nostream && (( bytecount % 8 == 0 )) # add a space down the middle
then
echo -n " "
fi
if (( bytecount % 16 == 0 )) # print 16 values per line
then
$nostream && echo "|$string|"
string=''
valcount=0
$nostream && printf "%08x " $bytecount
fi
done
if [[ "$string" != "" ]] # if the last line wasn't full, pad it out
then
length=${#string}
if (( length > 7 ))
then
((length--))
fi
(( length += (16 - valcount) * 3 + 4))
$nostream && printf "%${length}s\n" "|$string|"
$nostream && printf "%08x " $bytecount
fi
$nostream && echo
LANG="$saveLANG";
IFS="$saveIFS"
以下是脚本的一些输出,显示了我的如果前导字符是单引号或双引号,则值应为紧随其后的字符在底层代码集中的数值。
/bin/bash
的前几行以及更多内容:
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 03 00 01 00 00 00 e0 1e 06 08 34 00 00 00 |............4...| 00000020 c4 57 0d 00 00 00 00 00 34 00 20 00 09 00 28 00 |.W......4. ...(.| 00000030 1d 00 1c 00 06 00 00 00 34 00 00 00 34 80 04 08 |........4...4...| . . . 00000150 01 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 |..../lib/ld-linu| 00000160 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 |x.so.2..........| 00000170 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 |....GNU.........|
hexdump -C
或 hd
相同。 - Dennis Williamson如果您有hexdump,也可以使用它
hexdump -x /usr/bin/binaryfile
od -An -v -tx1 | tr -d ' \n'
例子:
printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -An -v -tx1 | tr -d ' \n'
输出:
3031323334353637383961626364656630313233343536373839616263646566000102030405060708090a0b0c0d0e0f
所以没有空格或换行符,只有十六进制。
在Ubuntu 23.04上进行了测试。