How do you write specific bytes to a file?

Given a file myfile with the following contents:

$ cat myfile
foos

A hexdump of the file gives us the contents:

$ hexdump myfile
6f66 736f 000a

Currently, I can create the file by specifying the contents in ascii like this:

$ echo foos > myfile

Is it possible to create the file by giving it the exact bytes in hexadecimal rather than ascii?

$ # How can I make this work?
$ echo --fake-hex-option "6f66 736f 000a" > myfile
$ cat myfile
foos

Update: For clarity’s sake, I worded the question to ask how to write a small number of bytes to a file. In reality, I need a way to pipe a large amount of hexadecimal numbers directly into a file rather than just 3 bytes:

$ cat hexfile
6f66 736f 6f66 736f ...
$ some_utility hexfile > myfile
$ cat myfile
foosfoosfoosfoos...
Asked By: Cory Klein

||

You can use echo -e:

echo -e "x66x6fx6f"

Do note that hexdump -C is what you want to dump the contents of the file in byte order instead of being interpreted as 4-byte words in network byte order.

Answered By: Dennis Kaarsemaker

This is the hexundump script from my personal collection:

#!/usr/bin/env perl
$^W = 1;
$c = undef;
while (<>) {
    tr/0-9A-Fa-f//cd;
    if (defined $c) { warn "Consuming $c"; $_ = $c . $_; $c = undef; }
    if (length($_) & 1) { s/(.)$//; $c = $1; }
    print pack "H*", $_;
}
if (!eof) { die "$!"; }
if (defined $c) { warn "Odd number of hexadecimal digits"; }

Simulate a byte train:

echo 41 42 43 44 | 

Change spaces into newlines so the while/read can easily parse them on by one

tr ' ' 'n' | 

Parse byte by byte

while read hex; do

Convert hex to ascii:

  printf \x$hex

until end of input

done

If the files to parse are seriously big, you probably don’t want to use bash because it is slow. PERL for example would be a better choice.

Answered By: jippie

The *some_utility* you’re finding is dd (manual). You can copy any valid bytes from any valid position of a file to another file by specify bs(block size), count, and skip options.

Example

Copy the first 1024 bytes of a file to another file.

$ dd if=liveusb-creator-3.11.7-setup.exe of=test.ex_ bs=1 count=1024
1024+0 records in
1024+0 records out
1024 bytes (1.0 kB) copied, 0.03922 s, 26.1 kB/s
Answered By: LiuYan 刘研

Here’s an example of how you can use dc to Print the (UCHAR_MAX+1) value of a byte:

printf %dP 104 101 121 32 116 104 101 114 101 10 |dc

…which prints…

hey there

The default input radix is 10 – decimal – but you can set it with $val i where $val is any number between 2 and 16 (note that if the current input radix is not 10 you’ll have to use the current base’s value for 10 to get it back – else you can always do Ai).

Here is a more complicated example:

LC_ALL=C man man 2>/dev/null | 
od -v -An -t x1 |
tr -s '[:space:]' P | {
    echo 16i0
    tr '[:lower:]' '[:upper:]'
} | dc | head

…which translates man man‘s output into hexadecimal and back again in-stream and prints:

MAN(1)              Manual pager utils              MAN(1)



NAME
       man - an interface to the on-line reference manuals

SYNOPSIS
       man [-C file] [-d] [-D] [--warnings[=warnings]] [-R
       encoding] [-L locale] [-m system[,...]]  [-M  path]

Just ensure that all of your alphabetic [:hexdigit:]s are uppercase and sandwich a P between every pair then pipe it at dc.

Answered By: mikeserv

To write arbitrary hex data to binary file:

echo -n 666f6f | xxd -r -p - file.bin

For hex (input) data stored in some file to be written to binary file:

xxd -r -p file.hex file.bin

To read binary data:
hd file.bin or xxd file.bin

To read data only (without offsets):

xxd -p file.bin
Answered By: Zimba
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.