Vim modifying a file if used with xxd
Pregunta
I'm trying to understand how ID3 tags work, so, after reading some documentation, I started to look at some mp3's raw data. Vim is usually my editor of choice, so, after some googling, I found out I could use xxd to see an hex representation of my files by invoking
:%!xxd
Everything worked fine, but when I put everything back in order with
:%!xxd -r
and quit, I found out that the file was modified; vlc could no longer play it, and diff told me the files differed. I thought I modified something by accident, but further experiments showed me that even opening the file and using xxd and then xxd -r changes somehow the file.
Why is that? How can I prevent it from happening? Am I doing something wrong?
Solución
Obviously if you do not intend to change anything to a file you could quit vim
using :q!
.
As @RunHolt points out, vim
and xxd
can change a binary file. e.g. changing LF to CRLF or appending an LF character at the end of file.
You can prevent this by setting the binary
option:
Either start vim
as: vim -b filename
or type :set binary
before loading the file into the buffer.
Otros consejos
You probably did not load the file as a binary file with vim -b
. I.e. the damage was already done.
xxd
is a red herring here; xxd
followed by xxd -r
is transparent. It is intended for editing binary files. xxd
does not add any bytes; it produces an accurate hexdump, which is accurately reversed by xxd -r
(unless you corrupt it).
For viewing only, you could just run xxd
from the shell:
$ xxd binaryfile | vim - # just use vim as a reader
I've edited executables with vim -b
and filtering through xxd
and back through xxd -r
. They ran fine.
Also, xxd is a Vim-specific program that comes with the Vim distribution. It might be useful to you to know od
, e.g
od -tx1 file
On windows binary files (not sure about other platforms), :%!xxd
puts the end-of-file marker in the last two bytes (0x0d, 0x0a). For some reason %!xxd -r
doesn't remove them.
I often remove them manually (just delete both characters than run %!xxd -r
)
Might be something that could be fixed directly with xxd
.