vim windows tips

いやそんな大したことじゃないよ ? とりあえず sort と uniq くらいはできないもんかと思って調べたことをまとめておく。

  • sort
    • Windows 標準の sort コマンドを使えば OK 。 :%!sort で今開いてるファイル全体を、 かなんかで範囲選択した後に :'<,'>!sort で任意の範囲を sort してくれる。まぁ基本が DOS prompt だから大したことはできないけど csv 程度なら /+N オプションを使えば任意の column で sort できる。
  • uniq
    • Windows 標準では存在しないので自前で用意しなきゃいけない。
    • 結論から行くと wsh / perl / ruby / gawk あたりで自分で書くのがいいのかもしれない。俺は JScript ( wsh ) と perl で書いたんだけど扱いやすさから JScript を選択。ていうか最初 perl で書いたんだけど DOS prompt の標準入出力の貧弱さに泣いて wsh に switch 。
    • で、標準入力をきっちり使えるようにしつつ CUI 用コマンドとして機能するために ( cscript.exe のみで起動 ) どうすればいいかなーといろいろあさってたら http://d.hatena.ne.jp/nobusuke_neko/20080626/1214505761 にそのものずばりのものがあった。いやまぁ上記 URL では -u をエミュレートしてるけどほしい処理は自分で書けばいいしな。
    • なんか wsh には @if, @end っていう C 言語でいう preprocessor みたいなモンがあんのね。 http://msdn.microsoft.com/ja-jp/library/ct27x3xa.aspx に書いてあるけどあんまり詳しい情報じゃないなー。まぁいいか。この手法を使えば独自コマンドが簡単に定義できちゃうな。いい感じ。 id:nobusuke_neko++ と同時に thanks 。
    • というわけで uniq.cmd という名前で以下のスクリプトを保存して vim から見えるところに置いておくと :%!sort | uniq という素敵 spell が使えるようになるわけだ。
@if (false)==(false) echo off
cscript //Nologo /E:JScript "%~f0" %*
goto :EOF
@end

var prev, line;
for( ; !WScript.StdIn.AtEndOfStream ; ) {
    line = WScript.StdIn.ReadLine();
    if( prev != line ) WScript.StdOut.WriteLine(line);
    prev = line;
}

元データ

aaa
aaa
aaa
bbb
bbb
ccc
ccc
ccc
ddd
ddd
aaa
aaa
aaa
aaa
aaa
bbb
bbb

:%!sort | uniq 適用後

aaa
bbb
ccc
ddd

んでここらへんが充実すると何が嬉しいかってはてなダイアリーのカテゴリ整理が楽になるんだよね。設定 -> 編集設定 -> カテゴリーの textarea 要素の中身を全部 vim に持ってきて整理して貼り付け。けっこうめんどくさいんだけどふったカテゴリ一覧を自動で抽出する機能とか提供してくれないんかなー。