Gitリポジトリ内をgrepする git grep はシンプルで超便利
Gitリポジトリ内を検索する機会はよくあると思います。
- このメソッドって、どこで使われてるんだっけ?
- その定数の定義って、値は何だっけ? どこにあるんだっけ?
- あのURLって、何箇所で使われているんだろう?
git grep
コマンドを使えば、Git管理下のファイルのみを対象としてgrepができます。
シンプルなコマンドですが、利便性はとても高いと思います。
目次
シンプルな例
シンプルな例ですが、よく使います。
特定ワードを含む箇所を調べたい(大文字小文字を区別する)
一番シンプルな例です。大文字小文字の区別をするので、注意が必要です。
$ git grep "lambda" hello_world /slash_command .py:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:def lambda_handler(event, context) -> dict: template.yaml: Handler: slash_command.lambda_handler tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
特定ワードを含む箇所を調べたい(大文字小文字を区別しない)
-i
オプションを使います。
$ git grep -i "Lambda" hello_world /slash_command .py:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:def lambda_handler(event, context) -> dict: template.yaml: - arn:aws:iam::aws:policy /service-role/AWSLambdaBasicExecutionRole template.yaml: Handler: slash_command.lambda_handler tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
行番号を表示したい
-n
オプションを使います。
$ git grep -n "lambda" hello_world /slash_command .py:4:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:7:def lambda_handler(event, context) -> dict: template.yaml:32: Handler: slash_command.lambda_handler tests /unit/test_handler .py:74: ret = app.lambda_handler(apigw_event, "" ) |
行番号表示は、Gitの設定でデフォルトONにできます。
$ git config --global grep .lineNumber true |
正規表現で検索したい
-E
オプションを使います。
次の例は「数字が2つ並んでいる箇所」です。
$ git grep -E "[0-9]{2}" hello_world /common_lambda .py: if res.status_code == 200: hello_world /requirements .txt:requests==2.20.0 hello_world /slash_command .py: "statusCode" : 200, template.yaml:AWSTemplateFormatVersion: '2010-09-09' template.yaml:Transform: AWS::Serverless-2016-10-31 template.yaml: Timeout: 10 |
単語で検索したい
-w
オプションを使います。
$ git grep -w "Function" template.yaml: Function: template.yaml: Type: AWS::Serverless::Function template.yaml: Type: AWS::Serverless::Function |
ちなみに-w
オプションが無い場合は次のような感じです(増えてますね)。
$ git grep "Function" template.yaml: Function: template.yaml: NotifyPeriodicFunction: template.yaml: Type: AWS::Serverless::Function template.yaml: NotifySlashCommandFunction: template.yaml: Type: AWS::Serverless::Function |
なお次を単語とみなしているようです。
- 行の先頭で始まる or 頭に単語以外の文字がある
- 行の終わりで終わるか or 単語以外の文字が続く
少し便利な例
ニッチな事例かもしれませんが、たまに役立つかもしれません。
- 特定フォルダのみで検索したい
- 特定フォルダを除外して検索したい
- 複数のワードを調べたい
- 表示時にファイル毎に空行を入れて見やすくする
- 不一致な行を調べたい
- 一致した行の上側を表示したい
- 一致した行の下側を表示したい
- 一致した行の上下を表示したい
- 一致した行を含む関数を表示したい
- ファイル名の一覧を調べたい
- 一致した数を調べたい(ファイル毎)
- 一致した数を調べたい(全体)
- 一致した数を調べたい(ファイル数)
- 複数ファイルの特定文字列を置換する(Git管理ファイルのみ)
特定フォルダのみで検索したい
-- <dir_name>
を使用します。
$ git grep lambda -- hello_world/ hello_world /periodic .py:from common_lambda import get_notify_delays, get_message hello_world /periodic .py:def lambda_handler(event, context) -> None: hello_world /slash_command .py:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:def lambda_handler(event, context) -> dict: |
特定フォルダを除外して検索したい
-- :^<dir_name>
を使用します。:^
がポイントです。
$ git grep lambda -- :^hello_world/ template.yaml: Handler: periodic.lambda_handler template.yaml: Handler: slash_command.lambda_handler tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
複数のワードを調べたい
--and
と--or
が使えます。ついでに--not
も使えます。パターンは-e
で指定する必要があります。
and
$ git grep -e lambda --and -e app tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
or
$ git grep -e lambda --or -e app hello_world /common_lambda .py: notify_delays.append(check_item) hello_world /common_lambda .py: details.append(f '・{company}: {name}: <{website}|こちら>' ) hello_world /periodic .py:from common_lambda import get_notify_delays, get_message hello_world /periodic .py:def lambda_handler(event, context) -> None: hello_world /slash_command .py:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:def lambda_handler(event, context) -> dict: template.yaml: Handler: periodic.lambda_handler template.yaml: Handler: slash_command.lambda_handler tests /unit/test_handler .py:from hello_world import app tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): tests /unit/test_handler .py: app.requests, 'get' , side_effect=requests_response_mock) tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
表示時にファイル毎に空行を入れて見やすくする
--break
オプションを使います。
$ git grep -- break lambda hello_world /periodic .py:from common_lambda import get_notify_delays, get_message hello_world /periodic .py:def lambda_handler(event, context) -> None: hello_world /slash_command .py:from common_lambda import get_notify_delays, get_message hello_world /slash_command .py:def lambda_handler(event, context) -> dict: template.yaml: Handler: periodic.lambda_handler template.yaml: Handler: slash_command.lambda_handler tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): tests /unit/test_handler .py: ret = app.lambda_handler(apigw_event, "" ) |
不一致な行を調べたい
-v
オプションを使います。あまり使いどころはないかもしれませんが……。
$ git grep - v "lambda" ...(略)... template.yaml:Description: Notify Slack Train Delay template.yaml: template.yaml:Globals: template.yaml: Function: template.yaml: Timeout: 10 template.yaml: template.yaml:Resources: template.yaml: template.yaml: NotifyPeriodicFunction: template.yaml: Type: AWS::Serverless::Function ...(略)... |
一致した行の上側を表示したい
-B <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と上側の2行」を表示しています。
$ git grep -B 2 lambda template.yaml- Properties: template.yaml- CodeUri: hello_world/ template.yaml: Handler: periodic.lambda_handler -- template.yaml- Properties: template.yaml- CodeUri: hello_world/ template.yaml: Handler: slash_command.lambda_handler -- tests /unit/test_handler .py- tests /unit/test_handler .py- tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): |
一致した行の下側を表示したい
-A <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と下側の2行」を表示しています。
$ git grep -A 2 lambda template.yaml: Handler: periodic.lambda_handler template.yaml- Runtime: python3.6 template.yaml- Policies: -- template.yaml: Handler: slash_command.lambda_handler template.yaml- Runtime: python3.6 template.yaml- Events: -- tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): tests /unit/test_handler .py- tests /unit/test_handler .py- requests_response_mock = namedtuple( "response" , [ "text" ]) |
一致した行の上下を表示したい
-C <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と上下の2行」を表示しています。
(「周辺をちょっと見たい」場合に使えそうですが、そのようなケースに遭遇したことはないです……)
$ git grep -C 2 lambda template.yaml- Properties: template.yaml- CodeUri: hello_world/ template.yaml: Handler: periodic.lambda_handler template.yaml- Runtime: python3.6 template.yaml- Policies: -- template.yaml- Properties: template.yaml- CodeUri: hello_world/ template.yaml: Handler: slash_command.lambda_handler template.yaml- Runtime: python3.6 template.yaml- Events: -- tests /unit/test_handler .py- tests /unit/test_handler .py- tests /unit/test_handler .py:def test_lambda_handler(apigw_event, mocker): tests /unit/test_handler .py- tests /unit/test_handler .py- requests_response_mock = namedtuple( "response" , [ "text" ]) |
一致した行を含む関数を表示したい
-W
オプションを使います。
関数の場合は良い感じにしてくれそうですが、YAMLファイルとか単なるTextファイルなどの場合は微妙です……(仕方がない)。
$ git grep -W lambda hello_world /periodic .py:def lambda_handler(event, context) -> None: hello_world /periodic .py- hello_world /periodic .py- notify_delays = get_notify_delays() hello_world /periodic .py- hello_world /periodic .py- if not notify_delays: hello_world /periodic .py- # 遅延が無ければ通知しない hello_world /periodic .py- return hello_world /periodic .py- hello_world /periodic .py- # Slack用のメッセージを作成して投げる hello_world /periodic .py- (title, detail) = get_message(notify_delays) hello_world /periodic .py- post_slack(title, detail) hello_world /periodic .py- hello_world /periodic .py- return |
ファイル名の一覧を調べたい
-l
オプションを使います。「xxxメソッドを変更するため、対象ファイルを知りたい」とかで使ってます。
$ git grep -l lambda hello_world /periodic .py hello_world /slash_command .py template.yaml tests /unit/test_handler .py |
一致した数を調べたい(ファイル毎)
-c
オプションを使います。
$ git grep -c lambda hello_world /periodic .py:2 hello_world /slash_command .py:2 template.yaml:2 tests /unit/test_handler .py:2 |
一致した数を調べたい(全体)
wc -l
コマンドと組み合わせて、改行の数をカウントしています。
$ git grep lambda | wc -l 8 |
一致した数を調べたい(ファイル数)
こちらもwc -l
コマンドと組み合わせます。
$ git grep -l lambda | wc -l 4 |
複数ファイルの特定文字列を置換する(Git管理ファイルのみ)
ファイル一覧を取得して、後段で1ファイルずつ置換処理させています。
1 | $ git grep -l '検索対象の文字列' | xargs sed -i '' -e 's/置換対象の文字列/置換後の文字列/g' |
さいごに
長く書きましたが、次の3つが使えればとりあえず便利です!
git grep xxx
- シンプル版
git grep -i yyy
- 大文字小文字を区別しない版
git grep -E zzz
- 正規表現版