概要
vimで編集中に、たまにシェルのコマンドを使ってファイル内を加工したい時がある。
わざわざ別のファイルに加工したい箇所を切り出して、vimを一旦抜けたり、ターミナルを新たに立ち上げたりするのは面倒。
:terminal
コマンドを使えば、vimを抜けずにシェルを操作できるためそこそこ楽。
しかし、もっと楽な方法がある!!
vimは、指定した範囲を標準入力としてシェルコマンドに渡して実行することができる
のだ!!
実行結果は、そのままファイル内の指定した範囲に反映される。
vimを抜けることなく、vim内からそのままgrep, awk, sort, sed, tr...などのコマンドが使えるため、かなり強力なテキスト処理が可能となる。
やり方
やり方は単純で、以下のようにすれば良い。
" 基本的な書式
:範囲!シェルコマンド
" 具体的な書式
:%!シェルコマンド " カレントバッファ(編集中のファイル)内に適用
:'a,'b!シェルコマンド " マークした範囲内に適用
:'<,'>!シェルコマンド " ビジュアルモードの選択範囲に適用(ビジュアルモード時に:すると自動で'<,'>が挿入される)
:m,n!シェルコマンド " m行目~n行目に適用
構文自体は:[範囲][コマンド]
という置換などと同じものだ。!
はシェルコマンドを意味する。
別の言い方をすると:!シェルコマンド
に範囲指定を加えただけ、ということ。(※)
しかも、通常のシェルのようにパイプ(:範囲!シェルコマンド1|シェルコマンド2|...
)を使うことも可能。
(もちろん、最初からvimを開いていなくてターミナルで作業している場合はそのままターミナルで作業した方が早いです)
※(補足)そもそもvimは、:!シェルコマンド
でシェルのコマンドを呼び出せる。
知らない人は、:!ls
とかしてみると良いかと。
使用例
- 例) 下記のファイルから、"hoge"を含む行を削除する
編集したいファイル
abc
def
hoge
ghi
jkl
hoge
mno
pqr
hoge
stu
:%!grep -v 'hoge'
実行結果
abc
def
ghi
jkl
mno
pqr
stu
- 例) 下記の[]内をアルファベット順にソートする
"cSpell.userWords": [
"yaegassy",
"eruby",
"intelephense",
"kalisi",
"autoclosing",
"autoload",
"vetur",
"quots",
"nvim",
"mkdir",
"autoclose",
"neovim",
"solargraph",
"dein",
]
vi] " []内をビジュアルモードで選択
:'<,'>!sort " 選択範囲をsort(ビジュアルモード時に:すると自動で'<,'>が挿入される)
実行結果
"cSpell.userWords": [
"autoclose",
"autoclosing",
"autoload",
"dein",
"eruby",
"intelephense",
"kalisi",
"mkdir",
"neovim",
"nvim",
"quots",
"solargraph",
"vetur",
"yaegassy",
]
※vimに:sort
コマンドがあるため、そちらを使った方が良いですが、例として一応挙げておきます。