How to print only the hex values from hexdump without the line numbers or the ASCII table?
You can specify the exact format that you want hexdump
to use for output, but it's a bit tricky. Here's the default output, minus the file offsets:
hexdump -e '16/1 "%02x " "\n"' file.bin
(To me, it looks like this would produce an extra trailing space at the end
of each line, but for some reason it doesn't.)
How to convert hex to ASCII while preserving non-printable characters
xxd
expects two characters per byte. One A
is invalid. Do:
printf '%02X' 10 | xxd -r -p | xxd -p
How to convert hex to ASCII while preserving non-printable characters
Use xxd
. If your input has one character, pad it with an initial 0
.
ASCII does not preserve non-printable characters
It does preserve any bytes, xxd
is the common tool to work with any binary data in shell.
Is it possible to preserve these characters somehow?
Yes - input sequence of two characters per byte to xxd
.
Show Hexadecimal Numbers Of a File
Edit: Added "bytestream" functionality. If the script name contains the word "stream" (e.g. it's a symlink such as ln -s bash-hexdump bash-hexdump-stream
and run as ./bash-hexdump-stream
), it will output a continuous stream of hex characters representing the contents of the file. Otherwise its output will look like hexdump -C
.
It takes a bunch of trickery since Bash isn't really good at binary:
#!/bin/bash
# bash-hexdump
# by Dennis Williamson - 2010-01-04
# in response to http://stackoverflow.com/questions/2003803/show-hexadecimal-numbers-of-a-file
# 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"
The apostrophe trick is documented here. The relevant part says:
If the leading character is a
single-quote or double-quote, the
value shall be the numeric value in
the underlying codeset of the
character following the single-quote
or double-quote.
Here is some output from the script showing the first few lines of my /bin/bash
plus a few more:
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.........|
Dump a ```sha``` checksum output to disk in binary format instead of plaintext hex in bash
Found it! After a bit more digging in forums / man pages, xxd
is able to solve it for me (found it here: https://gist.github.com/dstebila/6194f90097c43c091dd2 ):
# Convert hex to binary using xxd's reverser in plain hexdump style
xxd -r -ps
So xxd
is able to take a file filled with ASCII hexdump, and convert it to a binary content:
$ echo "48454C4C4F" > test.hex
$ xxd test.hex
00000000: 3438 3435 3443 3443 3446 0a 48454C4C4F.
$ xxd -r -ps test.hex > test.bin
$ xxd test.bin
00000000: 4845 4c4c 4f HELLO
$ ls -lrth test.hex
-rw-r--r-- 1 jrlab jrlab 11 mars 2 15:44 test.hex
$ ls -lrth test.bin
-rw-r--r-- 1 jrlab jrlab 5 mars 2 15:44 test.bin
Related Topics
Installing Qt on Linux, Cannot Find -Lgl
How to Check If Find Command Didn't Find Anything
How to Recursively Search for Files with Certain Extensions
How to Set Cap_Sys_Nice Capability to a Linux User
How to Add a String to the Beginning of Each File in a Folder in Bash
Linux Mail < File.Log Has Content-Type: Application/Octet-Stream (A Noname Attachment in Gmail)
How to Get Ec2 Load Balancing Properly Set Up to Allow for Real Time File Syncing
Merge/Join Two Tables Fast Linux Command Line
Interrupt Handling and User Space Notification
How to Check a File Exists and Execute a Command If Not
How to Force Node.Js Require to Be Case Sensitive
What Does "$" Give Us Exactly in a Shell Script
Remove Occurrences of String in Text File
Bash: Get List of Commands Starting with a Given String
When Should Xargs Be Preferred Over While-Read Loops
Getting Exit Status Code from 'Ftp' Command in Linux Shell
How to Identify Multiple Usb-Serial Adapters Under Ubuntu 10.1