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_messagehello_world/slash_command.py:def lambda_handler(event, context) -> dict:template.yaml: Handler: slash_command.lambda_handlertests/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_messagehello_world/slash_command.py:def lambda_handler(event, context) -> dict:template.yaml: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRoletemplate.yaml: Handler: slash_command.lambda_handlertests/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_messagehello_world/slash_command.py:7:def lambda_handler(event, context) -> dict:template.yaml:32: Handler: slash_command.lambda_handlertests/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.0hello_world/slash_command.py: "statusCode": 200,template.yaml:AWSTemplateFormatVersion: '2010-09-09'template.yaml:Transform: AWS::Serverless-2016-10-31template.yaml: Timeout: 10 |
単語で検索したい
-wオプションを使います。
$ git grep -w "Function"template.yaml: Function:template.yaml: Type: AWS::Serverless::Functiontemplate.yaml: Type: AWS::Serverless::Function |
ちなみに-wオプションが無い場合は次のような感じです(増えてますね)。
$ git grep "Function"template.yaml: Function:template.yaml: NotifyPeriodicFunction:template.yaml: Type: AWS::Serverless::Functiontemplate.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_messagehello_world/periodic.py:def lambda_handler(event, context) -> None:hello_world/slash_command.py:from common_lambda import get_notify_delays, get_messagehello_world/slash_command.py:def lambda_handler(event, context) -> dict: |
特定フォルダを除外して検索したい
-- :^<dir_name>を使用します。:^がポイントです。
$ git grep lambda -- :^hello_world/template.yaml: Handler: periodic.lambda_handlertemplate.yaml: Handler: slash_command.lambda_handlertests/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 apptests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "") |
or
$ git grep -e lambda --or -e apphello_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_messagehello_world/periodic.py:def lambda_handler(event, context) -> None:hello_world/slash_command.py:from common_lambda import get_notify_delays, get_messagehello_world/slash_command.py:def lambda_handler(event, context) -> dict:template.yaml: Handler: periodic.lambda_handlertemplate.yaml: Handler: slash_command.lambda_handlertests/unit/test_handler.py:from hello_world import apptests/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 lambdahello_world/periodic.py:from common_lambda import get_notify_delays, get_messagehello_world/periodic.py:def lambda_handler(event, context) -> None:hello_world/slash_command.py:from common_lambda import get_notify_delays, get_messagehello_world/slash_command.py:def lambda_handler(event, context) -> dict:template.yaml: Handler: periodic.lambda_handlertemplate.yaml: Handler: slash_command.lambda_handlertests/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 Delaytemplate.yaml:template.yaml:Globals:template.yaml: Function:template.yaml: Timeout: 10template.yaml:template.yaml:Resources:template.yaml:template.yaml: NotifyPeriodicFunction:template.yaml: Type: AWS::Serverless::Function...(略)... |
一致した行の上側を表示したい
-B <num>オプションを使います。<num>には数値を指定します。
次の例だと、「lambdaがヒットした行と上側の2行」を表示しています。
$ git grep -B 2 lambdatemplate.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 lambdatemplate.yaml: Handler: periodic.lambda_handlertemplate.yaml- Runtime: python3.6template.yaml- Policies:--template.yaml: Handler: slash_command.lambda_handlertemplate.yaml- Runtime: python3.6template.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 lambdatemplate.yaml- Properties:template.yaml- CodeUri: hello_world/template.yaml: Handler: periodic.lambda_handlertemplate.yaml- Runtime: python3.6template.yaml- Policies:--template.yaml- Properties:template.yaml- CodeUri: hello_world/template.yaml: Handler: slash_command.lambda_handlertemplate.yaml- Runtime: python3.6template.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 lambdahello_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- returnhello_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 lambdahello_world/periodic.pyhello_world/slash_command.pytemplate.yamltests/unit/test_handler.py |
一致した数を調べたい(ファイル毎)
-cオプションを使います。
$ git grep -c lambdahello_world/periodic.py:2hello_world/slash_command.py:2template.yaml:2tests/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- 正規表現版