あるキーワードが含まれているファイルをまとめて検索したいときはfindgrepを組み合わせるといいですね。

以下のような形でfindで取得したファイル名をxargsgrepに引き渡します。

$ find . -name {リストアップしたいファイル名のパターン} | xargs grep {検索したいキーワード}`

例はこんな感じです。たとえば、samplesディレクトリ配下のファイルで「kensaku」というキーワードが含まれているものをリストアップしたいときは以下のようにします。

find-nameオプションではファイル名のフィルタリングをすることができます。

以下の例では"*"としているので、全てのファイルが対象になります。

これを"*.txt"とすればテキストファイルのみをリストアップしてくれる感じですね。

$ cd samples
$ find . -name "*" | xargs grep kensaku`

以下は筆者の例です。あるプロジェクトのディレクトリ配下でRubyのファイル(拡張子が*.rb)のもので「select」の文字列が含まれているものを検索しました。

左側にはファイル名(./app/models/poker_room.rbなど)が表示されていて、その隣には検索で一致した部分が表示されています。

これはわかりやすいですね。

$ find . -name "*.rb" | xargs grep select
./app/models/poker_room.rb:    @voted_players ||= poker_players.select(&:voted?)
./app/models/poker_room.rb:    @voted_number_players ||= voted_players.select(&:voted_number?)
./app/models/todo_template_items/create_form.rb:      }.select { |_, v| v.present? }
./app/models/todo_list.rb:    todo_items.select(&:finished?).size
./app/models/todos/create_form.rb:      }.select { |_, v| v.present? }
./app/models/concerns/start_hours_selectable.rb:  def selectable_start_hours(last_hour: 23)
./spec/models/todo_templates/create_form_spec.rb:  describe '#selectable_start_hours' do
./spec/models/todo_templates/create_form_spec.rb:    let(:test_method) { TodoTemplateItems::CreateForm.new(todo_template_id: todo_template.id).selectable_start_hours }
./spec/models/todo_templates/create_form_spec.rb:      let(:test_method) { TodoTemplateItems::CreateForm.new(todo_template_id: todo_template.id).selectable_start_hours(last_hour: 26) }
./spec/models/todo_templates/create_form_spec.rb:      let(:test_method) { TodoTemplateItems::CreateForm.new(todo_template_id: todo_template.id).selectable_start_hours(last_hour: 26) }
./spec/models/todo_templates/create_form_spec.rb:      let(:test_method) { TodoTemplateItems::CreateForm.new(todo_template_id: todo_template.id).selectable_start_hours(last_hour: 26) }
./spec/models/todos/create_form_spec.rb:  describe '#selectable_start_hours' do
./spec/models/todos/create_form_spec.rb:    let(:test_method) { Todos::CreateForm.new(todo_list_id: todo_list.id).selectable_start_hours }
./spec/models/todos/create_form_spec.rb:      let(:test_method) { Todos::CreateForm.new(todo_list_id: todo_list.id).selectable_start_hours(last_hour: 26) }
./spec/models/todos/create_form_spec.rb:      let(:test_method) { Todos::CreateForm.new(todo_list_id: todo_list.id).selectable_start_hours(last_hour: 26) }
./spec/models/todos/create_form_spec.rb:      let(:test_method) { Todos::CreateForm.new(todo_list_id: todo_list.id).selectable_start_hours(last_hour: 26) }

ただ、検索する場所によっては以下のようにエラーメッセージや警告が多数表示されてしまって、肝心の検索結果が埋もれてしまう、みたいなことがあります。

# こんな感じのがたくさん出てくると、よくわからない・・
grep: ./tmp/postgres/base/5: Is a directory
grep: ./tmp/.draft: Is a directory
grep: ./tmp/.draft/videos: Is a directory
grep: ./.jekyll-cache: Is a directory
grep: ./.jekyll-cache/Jekyll: Is a directory
grep: ./.jekyll-cache/Jekyll/Cache: Is a directory
grep: ./.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown: Is a directory
grep: ./.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/fd: Is a directory
grep: ./.jekyll-cache/Jekyll/Cache/Jekyll--Cache: Is a directory
grep: ./.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7: Is a directory

そんなときはエラーメッセージの標準出力を/dev/nullに流すようにすると正常ケースのみが表示されるようになります。

grepコマンドを実行するところで2>/dev/nullと指定してあげます。

$ find . -name "*.rb" | xargs grep select 2>/dev/null

vscodeとか、JetBrainのエディタを使えば複数のファイルを検索する機能があるので、そちらを使ってもいいですがこっちはこっちでサクサク動くので快適なのがいいですね。

CUIしか使えないサーバーでも使えるのもいいところだと思います。

この記事の環境情報

  • macOS Ventura 13.1
  • 肉を焼いて食った