Edited at

findを使ったファイル内検索を強くしてみた

みなさんは複数のファイルからあるワードを検索したい時、どのような手法を用いていますか?

私はfindコマンドを使っています。

findはファイル"名"の検索によく用いられますが、findの実行結果をパイプでxargs grepに渡すことでファイルの中身を検索することもできます。

以下のコマンドを打つことで、カレントディレクトリ以下に存在する.ccファイルの中から、hogeというワードが含まれる行が出力されます。

find . -name "*.cc" | xargs grep "hoge" -n

このコマンドを応用して、以下のようなaliasを作ってみました。


.bash_aliases

function ff_orig(){

# 正規表現による条件指定で、拡張子が.ccまたは.hであるファイルについて検索
find . -type f -regextype posix-egrep -regex ".*\.(cc|h)" | xargs grep "$1" -n | nl | grep $1
}

function ff(){
# 第一引数:検索ワード
# 第二引数:エディタ(=vim)で開きたいファイルのindex
if [ $# -eq 1 ]; then
ff_orig $1
elif [ $# -eq 2 ]; then
vim `ff_orig $1 | sed -n $2p | cut -f 2 | cut -d: -f 1`
else
echo "error"
fi
}


例えば、ownerNameという名前の変数がどこで使われているか探したくなったとき、

上記のaliasを用いることで、カレントディレクトリ以下でownerNameが使われている.cc, .hファイルおよびその行が出力されます。

$ ff ownerName

1 ./qtenv/inspectorutil.cc:218: const char *ownerName = owner->getFullName();
2 ./qtenv/inspectorutil.cc:222: label = ownerName + QString(".") + name + " --> " + nextGateOwnerName + "." + nextGateName;
3 ./envir/sectionbasedconfig.cc:889: std::string ownerName;
4 ./envir/sectionbasedconfig.cc:891: splitKey(key.c_str(), ownerName, suffix);
5 ./envir/sectionbasedconfig.cc:895: if (!ownerName.empty())
6 ./envir/sectionbasedconfig.cc:896: entry2.ownerPattern = new PatternMatcher(ownerName.c_str(), true, true, true);
7 ./envir/sectionbasedconfig.cc:1176: std::string ownerName;
8 ./envir/sectionbasedconfig.cc:1178: splitKey(key, ownerName, suffix);

実際には、下画像のように検索ワードに色が付きます。

qiita投稿用.png

また、

$ ff ownerName 3

と打つと、sectionbasedconfig.ccをvimで開くことができます。

筆者は一日100回は使っています。