170

Is there a neat way I can view binary files as hex in Vim, and save it back to binary from the hex?

0

2 Answers 2

246

You can use the xxd command to transform a file in Vim to hex representation, doing

:%!xxd

: enters command-line mode, % matches whole file as a range, ! filters that range through an external command, xxd is that external shell command

Giving an output like this, this is split into octet count/line (octets per line may be changed with parameter -c on xxd command), hex representation, and text representation:

0000000: 5468 6973 2069 7320 6120 7465 7374 0a41  This is a test.A
0000010: 6e6f 7468 6572 206c 696e 650a 416e 6420  nother line.And 
0000020: 7965 7420 616e 6f74 6865 720a            yet another.

Once you make the changes (in the hex part), you can go back to text with -r command on xxd, so

:%!xxd -r

This is a little rudimentary, though I like it in its simplicity and to keep in mind xxd, which is an interesting command line tool (I don't have to do a lot of work on hex, though). You can use some recipes to handle this transformation in a more automatic way like the one described in Improved hex editing.

And rembember you can also use syntax highlighting for hex editing in vim with that command:

:set ft=xxd
7
  • 4
    I think it worths mentioning that after you make the changes you must go back to the normal mode before saving the changes.
    – kaptan
    Jul 26, 2018 at 20:52
  • 1
    Is it possible to specify the byte order? big-endian or little-endian
    – C--
    Apr 30, 2019 at 9:23
  • BTW. Where is :h for :%!? I could find only for :!. Using nvim.
    – Artyom
    May 18, 2020 at 7:55
  • 1
    Info: After changing a hex code in the middle of a file and finally comparing it with "Beyond Compare" I found out that vim added 0A to the end of the file. So it now has a different size (+ 1 Byte). I think a hex editor should not do such things. I used truncate --size=-1 to correct this.
    – mgutt
    Oct 16, 2020 at 21:59
  • Is there a plugin or other way that shows the connection between the bytes in hex format and decoded to ASCII? For example, when the cursor is at byte 54 it would highlight the T. Similar to how hexedit does it. Edit: this plugin should do it. Dec 16, 2020 at 20:27
29

Taken from :h hex-editing:

If one has a particular extension that one uses for binary files (such as exe,
bin, etc), you may find it helpful to automate the process with the following
bit of autocmds for your <.vimrc>.  Change that "*.bin" to whatever
comma-separated list of extension(s) you find yourself wanting to edit:

" vim -b : edit binary using xxd-format!
augroup Binary
  au!
  au BufReadPre  *.bin let &bin=1
  au BufReadPost *.bin if &bin | %!xxd
  au BufReadPost *.bin set ft=xxd | endif
  au BufWritePre *.bin if &bin | %!xxd -r
  au BufWritePre *.bin endif
  au BufWritePost *.bin if &bin | %!xxd
  au BufWritePost *.bin set nomod | endif
augroup END

You may want to look at: How do I navigate to topics in Vim's documentation?

3
  • This is perfect - I added it to ~/.vim/plugin/binary.vim
    – thom_nic
    Sep 6, 2017 at 15:55
  • Maybe this is must be in ~/.vim/ftdetect/ because this is about file type detection? Nov 28, 2018 at 7:36
  • You can add silent to avoid "hit enter to continue", and getpos and setpos to keep the current cursor position. That way it is easy to just save and check the asc-ii code.
    – DrBeco
    Jun 27, 2021 at 5:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.