vimでバイナリを表示し、値を変更したい
バイナリファイルを表示させることなら、
$ hexdump -C picture.png 00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| 00000010 00 00 00 0a 00 00 00 0f 08 02 00 00 00 52 9d c9 |.............R.?|
とか、
$ xxd picture.png 0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 0000010: 0000 000a 0000 000f 0802 0000 0052 9dc9 .............R..
みたいに、hexdumpコマンドとかxxdコマンド(この記事を書いてて知った)を使えばできる。
でも、値を変えたいときは、どうすれば良いのか。
それ、vimで、できるよ。
vimはスゴい
http://www.ac.cyberhome.ne.jp/~yakahaira/vimdoc/usr_23.html#23.4
本物のバイナリエディタは、テキスト表示と 16 進表示の二通りの方法でファイルを表 示します。"xxd" を使ってファイルを変換すれば Vim でも同じように表示できます。 "xxd" は Vim に付属しています。 まず、ファイルをバイナリモードで開いてください: vim -b datafile そして、xxd を使って16進数ダンプ形式に変換します: :%!xxd テキストは次のように変換されます: 0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49 ....9..;..tt.+NI 0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30 K,.`.....b..4^.0 0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9 7;'1.".....i.59. あとは、好きなようにテキストを編集してください。普通のテキストを編集するのと同 じです。16 進数部分を変更しても、テキスト部分は更新されません。逆も同様です。 編集が済んだら変換し、テキストに戻します: :%!xxd -r 16 進数部分への変更だけが反映されます。右側のテキスト部分への変更は無視されま す。
以下の手順を踏めばできるよ、ってことです。
-
-
- > バイナリモードでファイルを開く(オプション -b)
- > コマンド%!xxdにより現在開いているバッファをバイナリ表示する
- > 任意の箇所を変更。
- > コマンド%!xxd -rによりテキスト表示に戻す
-
でも、こんなに手順を踏むのは面倒ですよね。
面倒から解放されたい。
それ、vimで、できるよ。
vimは賢い
http://www.ac.cyberhome.ne.jp/~yakahaira/vimdoc/tips.html
もしそのファイルがバイナリファイル特有の拡張子(exe、binなど)をしているときは、 あなたの<.vimrc>に次のオートコマンドを加えることで、変換の過程を自動化しておく こともできます。"*.bin"をあなたの編集したいファイルの拡張子の、カンマで区切ら れたリストに変えてください: " 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
ただ、このままの設定では、拡張子binにしか適応されません。
目標は拡張子がなんであっても、バイナリモードでファイルを開いたらバイナリで表示してくれること。
それ、vimで、できるよ。
vimが好きです
http://www.kawaz.jp/pukiwiki/?vim#notefoot_1
"バイナリ編集(xxd)モード(vim -b での起動、もしくは *.bin ファイルを開くと発動します) augroup BinaryXXD autocmd! autocmd BufReadPre *.bin let &binary =1 autocmd BufReadPost * if &binary | silent %!xxd -g 1 autocmd BufReadPost * set ft=xxd | endif autocmd BufWritePre * if &binary | %!xxd -r | endif autocmd BufWritePost * if &binary | silent %!xxd -g 1 autocmd BufWritePost * set nomod | endif augroup END
ちょっと説明してみる。
augroup BinaryXXD
コマンドのグループ化をしています。グループ名はBinaryXXDになってます。
グループ名は任意に設定できる。
autocmd!
このグループのautocmdをすべて削除しています。初期化ですね。
autocmd BufReadPre *.bin let &binary =1
vim -b での起動、もしくは *.bin ファイルを開くと
ファイルを読み込む前に変数binaryに1をセットする。
autocmd BufReadPost * if &binary | silent %!xxd -g 1
ファイルが読み込まれた後に変数binaryに1がセットされているならば、
コマンド%!xxd -g 1を実行。(オプション-g 1によって1バイト表示になる。defaultは2バイト)
はコマンドの追記。 |
silent は"続けるにはENTERを押すかコマンドを入力してください"みたいなメッセージを表示されコマンドが止まるのを防ぐために書かれています。
autocmd BufReadPost * set ft=xxd | endif
ft(filetype)をxxdに、つまりバイナリに設定して、if文を終了します。
これにより視覚的に見やすくなります。
set ft=xxdを適用後↓
autocmd BufWritePre * if &binary | %!xxd -r | endif autocmd BufWritePost * if &binary | silent %!xxd -g 1 autocmd BufWritePost * set nomod | endif
ここは、:wとコマンドを実行して保存する前にテキストファイルに戻してやって、保存したらバイナリ表示にするという
設定です。
vimは何でもできる。
.vimrcに以上のautocmdを記述しておくことにより、バイナリの編集が非常に便利になりました。
例えば、pngファイルをバイナリで開いて値を変更したい場合は以下のようにします。
$ vim -b picture.png
すると、以下のようにバイナリで表示してくれるから。
任意の箇所の値を変更して、保存して、終了すればいい。
[
以下のように新しいバッファを開くと、それもバイナリで表示される。
(vimをオプション-b、つまりバイナリモードで起動しているため)
もし、バイナリで表示したくなくなりテキスト表示をしたいならば、
以下のようにバイナリ表示用のaugroupを無効にしてやればいい。
これによって、新しく開いたバッファはテキストファイルとして表示される。