grepで検索した結果のファイルをすぐにvimの複数タブで開くコマンドを作る


概要

grepして引っかかったファイルをコピーしてペーストしてvimを開くことが多かったので、これってもしかしてめっちゃ時間を無駄にしているのでは、と思いました。
ということで専用のコマンドを書いてみました。

コマンドの実装

実行環境

zsh派なので、.zshrcで動作確認していますが、多分bashでも動くと思います。

実装

~/.zshrc
function svim() {
    if [ "$1" = "" ]
    then
        echo 'no arguments';
        return;
    fi
    vim -p `grep -lr $1 $2 | perl -pe 's/\n/ /g'`;
}

使い方

svim {引数}で、カレントディレクトリは以下のファイルを引数の文字列で検索し、ヒットしたファイルを全てvimで開きます。第2引数にフォルダを指定すると、そのフォルダの中で検索します。

$ svim HOGEHOGE
または
$ svim HOGEHOGE src/components

解説

せっかくなのでちょっとした解説も書きます。

引数チェック

最初に、引数が0、つまり$1 = ""のときはreturnします。

grep

-lrオプションで、ファイル名だけを羅列し、かつ配下のディレクトリを再帰的に検索します。

$ grep -lr hoge *                                                                                
Resources/views/base.html.twig
Resources/data/page.yml

perl

次に、perlを使って改行を全て空白に置換することで、検索結果のファイル名を横並びにします。
-peオプションを付けることで、sedコマンドのようにs/hoge/fuga/gの書式を使った検索ができます。

$ cat sample.txt 
hoge
fuga
foo
bar

$ cat sample.txt | perl -pe 's/\n/ /g'
hoge fuga foo bar % 

vim

最後にvimですが、vim-pオプションを付けて開くことで、複数ファイルをタブで一度に開くことができます。

$ vim -p sample.txt sample2.txt 
2 files to edit

こんなふうに開きます。

僕はvimのショートカットをいろいろ変えていて、snとかspでタブを前後移動できるため、タブで開くほうが都合が良かったのです。

余談

以上になりますが、理想を言えばgrepした検索結果があまりにも多いとvimがパンクしてしまうので、grep結果の件数を見てフィルタリングしたいなと思います。

余談Ⅱ

あっvimgrepというものがあるのか、知らなかった。とはいえシェル上から探したい場面もあると思うので両方使えるようにこっちも勉強してみます。