17

I converted a simple binary file into a text file with:

od –t x1 Check.tar | cut –c8- > Check.txt

Which gives a content similar to:

 64 65 76 2f 6e 75 6c 6c 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 [...]

What is the opposite way -- to convert Check.txt to Check.tar as the original file?

9
  • 1
    Maybe xxd -r -p Check.txt > Check.tar
    – cuonglm
    Commented May 26, 2015 at 9:13
  • its still text file , isnt work Commented May 26, 2015 at 9:17
  • What leads you to believe it's still a text file? xxd -r -p is the exact reverse of the od conversion you did; the output of cuonglm's command should be strictly identical to the original tarball. Commented May 26, 2015 at 9:24
  • xxd -r -p Check.txt > Check.tar ..... file Check.tar Check.tar: ascii text Commented May 26, 2015 at 9:26
  • I also try this - tar xvf Check.tar tar: directory checksum error Commented May 26, 2015 at 9:28

3 Answers 3

12
od -An -vtx1 Check.tar > Check.txt

You need -v or od will condense sequences of identical bytes.

For the reverse:

LC_ALL=C tr -cd 0-9a-fA-F < Check.txt | xxd -r -p > Check.tar

Or:

perl -ape '$_=pack "(H2)*", @F' Check.txt > Check.tar

If your purpose is to transfer files over a channel that only supports ASCII text, then there are dedicated tools for that like uuencode:

tar cf - myfiles.* | xz | uuencode myfiles.tar.xz | that-channel 

And to recover those files on the other end:

uudecode < file.uu

would recreate myfiles.tar.xz.

Or:

uudecode -o - < file.uu | xz -d | tar xf -

To extract the files.

13
  • first thanx for the answer , but I need to create file.tar file , how to do it? Commented May 26, 2015 at 10:12
  • @maihabunash If you created file.txt without -v and with removing the address, then you can't reliably recover file.tar if there were condensed sequences (do a grep '[*]' file.txt to check) as you've lost the information of how long those condensed sequences were by removing the address. Commented May 26, 2015 at 10:22
  • hi , my target is to compress more then 30 perl script with tar or zip or whatever then convert it to text and then convert it back to compressed file , is it possible? ( I see tar is problem but can we do it with other options ) Commented May 26, 2015 at 10:31
  • 1
    @maihabunash, you're looking for uuencode or base64 encoding. Note that my answer covers your question. I give the code to convert back to binary from od output provided you don't forget the -v option. If you're transferring files over FTP, don't forget to set the mode to "binary" (TYPE I FTP command, something like binary in your client) Commented May 26, 2015 at 10:50
  • 1
    @pmor, It looks like you want the output of xxd -p which can be decoded with xxd -r -p. the tr | xxd -r -p approach already removes all whitepace (anything but xdigits). perl -pe 'chomp;$_=pack"H*",$_' to decode the output of xxd -p Commented May 26, 2023 at 16:24
6

Answering the X part of this XY problem, I would recommend you investigate the reason your binary file transfers don't transfer properly.

If it turns out the reason is because you don't have an 8-bit clean datapath you could then use existing tools that were created to handle this situation, such as base64 or even uuencode. Old but still very effective.

tar czvf - /etc/h* | base64 >/tmp/tar.tgz.b64
ls -l /tmp/tar.tgz.b64
-rw-r--r-- 1 root root 7364 May 26 11:52 /tmp/tar.tgz.b64
...
base64 -d /tmp/tar.tgz.b64 | tar tzvf -

or

tar czvf - /etc/h* | uuencode - >/tmp/tar.tgz.uue
ls -l /tmp/tar.tgz.uue
-rw-r--r-- 1 root root 7530 May 26 11:51 /tmp/tar.tgz.uue
...
uudecode /tmp/tar.tgz.uue | tar xzvf -
2
  • Upvote +1 for you thx Commented May 26, 2015 at 11:34
  • +1 for suggesting base64, which works on my relatively fresh cygwin install.
    – mwfearnley
    Commented Nov 19, 2015 at 9:18
3

In my case I didn't have xxd or uudecode on the remote device but I did have bash. I ended up with the following:

Convert from binary to txt with:

od -An -vtx1 myfile.bin > myfile.txt

Then convert back from txt to binary with:

while read p; do
    IFS=' ' read -r -a array <<< "$p" 
    for index in "${!array[@]}" 
    do
        echo -en "\x${array[index]}" 
    done
done < myfile.txt > myfile.bin

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .