Using vi as a hex editor

Sometimes I find it useful to switch to hex mode when editing a file in vi. The command for switching is not very obvious so thought I’d share…

So, open a file in vi as usual, hit escape and type:
:%!xxd to switch into hex mode

And when your done hit escape again and type:
:%!xxd -r to exit from hex mode.

Okay, so this isn’t actaully switching to vi’s ‘hex mode’; vi doesn’t have one. What the above actually does is to stream vi’s buffer through the external program ‘xxd’.

  • Javier

    Very nice!, vi is the gratest editor ever made.

  • raghu

    Thanks mate. :)

  • jorgenorid

    Thanks for the tip :)

  • santosh

    Thanks, it is very useful.

  • dR_schneider

    I found a problem using the suggested vi command (:%!xxd). I opened a network dump file with vi and then switched on hexmode. To my suprise the bytes seemed wrong. I downloaded another hexeditor called ghex to verify that it I was right.
    Used vi version:
    VIM – Vi IMproved 7.2

    You can check if your own vi shows the hexcode incorrectly by generation your own network dump (cap) and then open it. The first 4 byte should problably be D4 C3 B2 A1, but vi is showing C3 94 C3 83

  • Joe

    Try adding the following to /etc/vim/vimrc.local, and you’ll get keyboard shortcuts for switching back and forth (F8 and F7).

    ” Switch to hex-editor
    noremap :%!xxd
    ” Switch back
    noremap :%!xxd -r

  • Joe

    (Repost, it ate my code. Preview would be a good feature).

    Try adding the following to /etc/vim/vimrc.local, and you’ll get keyboard shortcuts for switching back and forth (F8 and F7).

    " Switch to hex-editor
    noremap <F8> :%!xxd<CR>
    " Switch back
    noremap <F7> :%!xxd -r<CR>

  • Joe

    Try adding the following to /etc/vim/vimrc.local, and you’ll get keyboard shortcuts for switching back and forth (F8 and F7).

    ” Switch to hex-editor
    noremap <F8> :%!xxd<CR>
    ” Switch back
    noremap <F7> :%!xxd -r<CR>

  • hardly

    Thanks. That’s pretty rad. Just what I was looking for.
    I wanted a hex editor and had one the whole time. :-)

  • Chandrashekhar

    Thanks a ton for the tip!

  • http://www.fishdan.com Dan

    Great tip, I’m linking to it

  • rainer

    helped me a lot, thanks!

  • rock

    how to go to offset with it ?

  • kevin

    This is kind of misleading. That isn’t actually invoking any sort of ‘hex editor’ functionality of vi, it’s just streaming the file through the external application ‘xxd’. It’s certainly a nice tip, but if you want to understand what’s actually happening and how you can better control the conversion, the place to look is the xxd man page.

  • Dan Douglas

    This isn’t a “hex mode”. :! is Vim’s filter syntax. :%!xxd selects the range of the entire buffer, filters it through the external xxd program and replaces each line with the resulting output (though xxd appears to be part of the vim package on my distro, not a standard Linux command). You could accomplish the same by launching Vim with a bash command like “vim <(xxd filename)" assuming xxd is located in your $PATH. It should be nicely highlighted nicely if ft=xxd.

  • Steven

    Lousy vim

    Tried to save the file and it wrote the readable hex-code instead.

    The reversion is required!

    • ajubea

      Hi Steven,

      if you have accidentally saved the hex-code of your file, so you can revert to your original code using the command

      $:> xxd -r your_file_name

      this will do the reverse operation of xxd and convert the hex-code into the binary code.

  • ajubea

    Hi,

    if you have accidentally overwritten your file with the hex code then you can revert to the original file by using the command:

    xxd -r your_file_name

    This will do the reverse conversion from hex code to binary code.

  • Naveen

    Thanks a Lot, very useful

  • bill

    this is extremely useful. I was about to try teach myself how to use yet another command line text editor, so this saved me some time.

  • Ritesh

    Great tip! Thanks for sharing :)

  • Seriously

    xxd is an awesome program, and vi(m) is another one. [snip of insulting and obnoxious rant]

    So, if you ever read that, I don’t care if you remove this comment, AS LONG AS YOU CLEAR THINGS UP IN YOUR POST.

    [more snipping], here is a more correct version of it :

    ” Sometimes I find it useful to switch to hex mode when editing a file in vi. vi doesn’t have such a feature, but it has the capability of using an external program as a ‘filter’ (meaning that the input (stdin) of the program is taken from vi buffer, which is later replaced by its output (stdout)). xxd is the binary used to transform one’s binary into hexadecimal and vice versa. The vi command for using it as a filter is not very obvious so thought I’d share…

    So, open a file in vi as usual, hit escape and type:
    :%!xxd
    to switch into hex mode

    And when your done hit escape again and type:
    :%!xxd -r
    to exit from hex mode.

    As you can easily figure it out, ‘:[address-range] ! external-command-name’ is vi’s command for filtering. % as an address-range means : everything in the buffer. See http://www.softpanorama.org/Editors/Vimorama/vim_piping.shtml for further information.”

    • http://www.linuxinstead.com Kev

      Thanks for giving me a nudge and reminding me to update my post. It was quite overdue. I know that most people are only looking for the quick tip and don’t care how it works, but you’re right, the explanation was misleading.

  • Seriously

    Hey.

    Thanks for not suppressing (entirely) the comment. With more research I found that vi’s “hexadecimal mode” is a sort of urban legend, and, sadly, doesn’t only belong to your blog. It would be harsh to ask EVERY blog editor to correct their version (which on the top of that are all slightly different). So, I give up. The world gonna stay the stinking heap of lies it is.

    On the other hand your edits made me smile (I’m not being sarcastic by the way), and I don’t think my original text was that insulting. But I do agree, it wasn’t that nice either and it’s your blog.

  • sharp

    Thanksfor the info (and the commenters), I hope xxd works as well standalone as it does with vi.

  • http://www.bashoneliners.com/ Janos

    When you are creating a new binary file, you most probably want to set some flags before saving:
    :set noeol
    :set binary

    Otherwise vi will append a newline (0x0a) at the end of the file.

    This is only an issue when creating a new binary file. When you open an existing binary file vi automatically sets these flags for you.

    Janos
    http://www.bashoneliners.com/

  • Janos

    It gets better. Vim can do all the xxd filtering back and forth automatically if you add the following in your .vimrc:

    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 also get nice syntax highlighting (if you have syntax highlighting correctly setup in general).

    Change that “*.bin” to whatever comma-separated list of extension(s) you find yourself wanting to edit.

    This tip actually comes from :help hex-editing
    http://vimdoc.sourceforge.net/htmldoc/tips.html#hex-editing

    Cheers, Janos
    http://www.bashoneliners.com/

  • Joe

    Thanks a lot for the info and the corrections guys. I love Linux, but even after many years of use there are still new useful commands/features I find.

  • Tribio

    Thank you very much for this hint!
    I use GVim, and the command works like a charm!

  • Chris

    You need to invoke vi with the “-b” switch (binary), or else risk messing up the resulting binary:

    vi -b

  • Chris

    Add the following to the end of your /etc/vimrc or equivalent:-

    ” The following maps the F8 key to toggle between hex and binary (while also setting the
    ” noeol and binary flags, so if you :write your file, vim doesn’t perform unwanted conversions.

    noremap <F8> :call HexMe()<CR>

    let $in_hex=0
    function HexMe()
    set binary
    set noeol
    if $in_hex>0
    :%!xxd -r
    let $in_hex=0
    else
    :%!xxd
    let $in_hex=1
    endif
    endfunction

    • Husam

      Thanks, this is what I was looking for .. this way I can’t filter 2 times by mistake :)