vim-users.jp

Hack #140: Vimでバッチ処理を行なう

Posted at 2010/04/18
このエントリーをはてなブックマークに追加

問題

Vimはテキストエディタですから、通常は対話的に使います。 しかしVimの豊富な機能はテキスト処理用のスクリプト言語とみなすこともでき、 そう考えるとシェルなどから非対話的に利用したくなります。

例えばNormal modeでgg=Gを実行すると バッファ内容全体をファイルの種類に応じて適切にインデントします。 手元にインデントを修正したいファイルの数が多数あったとして、 この作業を手動で行なうのは面倒です。 非対話的に処理を行なうにはどうすればよいでしょうか。

解決方法

-c {command}オプションを指定してVimを起動します。 {command}はVimの起動後に実行されます。

例えばファイルのインデントを修正する場合、 以下のようにして非対話的に行うことができます。

$ cat hidoi.html
<title>This is hidoi</title>
<dl>
<dt>UWAAA</dt>
<dd>uwaaa</dd>
<dt>NANDATTE</dt>
<dd>nandatte</dd>
</dl>

$ vim -c 'normal! gg=G' -c 'write' -c 'qall!' hidoi.html

$ cat hidoi.html
<title>This is hidoi</title>
<dl>
    <dt>UWAAA</dt>
    <dd>uwaaa</dd>
    <dt>NANDATTE</dt>
    <dd>nandatte</dd>
</dl>

指定するコマンド数が多くなる場合は別のファイルにまとめて記述しておき、 -c 'source {file}'あるいは -S {file}で実行することもできます。

$ cat reindent.vim
normal! gg=G
write
qall!

$ vim -S reindent.vim hidoi.html

なお、上記のように実行した場合はvimrcなどが読み込まれ viminfoの内容も更新されます。 実行時の環境に依存せず実行するためには 以下のように実行します。

$ vim -u NONE -i NONE -N --cmd 'filetype indent on' -S reindent.vim hidoi.html
  • -u-NについてはHack #134: Vimをデフォルトの状態で起動するを参照してください。
  • -i {file}はviminfoファイルのパスを指定します。NONEはviminfoファイルを利用しないという意味です。viminfoはレジスタの内容やコマンドラインの履歴といった情報を保存しておくファイルなのですが、これを無効にしておかないとレジスタの内容を変更するような処理を実行した場合に後で困る可能性があります。
  • --cmd {command}-cと似ていますが、実行されるタイミングが違います。--cmdはファイルの読み込みなどに先立って実行され、-cはファイルの読み込みが完了した後に実行されます。ファイルの種類に応じたインデントを行なうにはVimがファイルの種類を自動認識するよう設定する必要があるのですが、それはファイルの読み込み前に行なわなければなりません。

応用例

筆者の場合、 拙作VimプラグインのドキュメントのHTML版 を公開していますが、これは :help形式のドキュメントからVimを利用してHTML版を自動生成 させています。

HTML化は

runtime! syntax/2html.vim

あるいは

TOhtml

で行なうことができますが、 ここではそれに加えて :help間のリンク(|:TOhtml|*:TOhtml*)を 適切なハイパーリンク(<a href="...">:TOhtml</a>)に 変換するなどの処理を行なっています。

参考資料

kana

もどる
blog comments powered by Disqus