MacやLinuxに慣れているとWindowsでもgrepを打ちたくなることってありますよね。ログファイルから「ERROR」だけ拾いたいとか、大量テキストから特定の文字列を探したいとか、SEや開発者であれば日常的な場面かと思います。
PowerShellにはSelect-Stringというコマンドレットがあり、grepとほぼ同じことが実現できます。デフォルトで正規表現に対応しているので慣れてしまえばgrepより柔軟に使えるケースもあります。
この記事ではSelect-Stringの基本的な使い方から実践的なパターンまでを解説します。
PowerShellでgrepに相当するコマンドとは
PowerShellでgrepに相当するのがSelect-Stringコマンドレットです。
ファイルや文字列の中から特定のパターンに一致する行を抽出してくれます。デフォルトで正規表現に対応しており、grepのように-Eオプションを別途つける必要がない点はちょびっとだけ便利かな~と思います。
なお、PowerShellにgrepという名前のエイリアスは存在しません。Windowsのfindstrコマンドと混同しやすいですがSelect-Stringのほうが機能が豊富でPowerShellらしい書き方ができます。
| コマンド | 環境 | 正規表現 | パイプ対応 |
|---|---|---|---|
grep | Linux / macOS | ○ | ○ |
findstr | Windows(コマンドプロンプト) | △(限定的) | ○ |
Select-String | PowerShell(Windows / macOS / Linux) | ○ | ○ |
Select-StringはPowerShell 5.1・7系いずれでも使えます。ただしPowerShell 5.1はWindows専用、7系はLinux・macOSでも動作する点が異なります。
Select-Stringの基本構文
Select-String -Path <ファイルパス> -Pattern <検索パターン>よく使うオプションは以下のとおりです。
| オプション | 説明 |
|---|---|
-Path | 検索対象のファイルパスを指定する。ワイルドカード(*)使用可。 |
-Pattern | 検索する文字列または正規表現パターンを指定する。 |
-CaseSensitive | 大文字・小文字を区別して検索する(デフォルトは区別しない)。 |
-NotMatch | パターンに一致しない行を抽出する(grepの-vに相当)。 |
-SimpleMatch | 正規表現を使わずリテラル文字列として検索する。 |
-List | 各入力ファイルについて、最初に一致した1件だけを返す。該当するファイルの一覧を効率よく確認するときに使う。 |
-Quiet | 一致したかどうかをTrue/Falseで返す。スクリプトの条件分岐に使いやすい。 |
詳細なパラメーター仕様はMicrosoft公式ドキュメントも参照してください。
基本的な使い方
ファイルから文字列を検索する
もっともシンプルな使い方です。
Select-String -Path "C:\logs\app.log" -Pattern "ERROR"app.log:15:2024-06-01 10:23:45 ERROR Something went wrong.
app.log:42:2024-06-01 11:05:12 ERROR Connection timeout.出力はファイル名:行番号:行の内容という形式になっています。どのファイルの何行目にあるかが一目でわかるのでログ調査のときに重宝します。
大文字・小文字を区別して検索する(-CaseSensitive)
Select-Stringはデフォルトで大文字・小文字を区別しません。区別して検索したい場合は-CaseSensitiveを追加します。
# 「error」は引っかからず「ERROR」だけ検索する
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" -CaseSensitive逆にオプションなしで使えばerror・Error・ERRORをまとめて拾えるということですね。
正規表現・複数条件で検索する(-Pattern)
-Patternは既定で正規表現として解釈されます。複数条件を指定する場合OR検索では|、AND検索ではSelect-Stringをパイプでつなぎます。-NotMatchを使うと指定したパターンを含まない行を抽出できます。
# OR:ERRORまたはWARNを含む行
Select-String -Path "C:\logs\app.log" -Pattern "ERROR|WARN"
# AND:ERRORとTimeoutの両方を含む行
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" |
Select-String -Pattern "Timeout"
# NOT:DEBUGを含まない行
Select-String -Path "C:\logs\app.log" -Pattern "DEBUG" -NotMatchタイムスタンプのように形式が決まっている文字列も正規表現で検索できます。
Select-String -Path "C:\logs\app.log" -Pattern "\d{4}-\d{2}-\d{2}"文字列で検索する(-SimpleMatch)
正規表現ではなく文字列をそのまま検索したい場合は-SimpleMatchを使います。
たとえば[や]などの正規表現で特別な意味を持つものは、そのまま検索すると意図しない結果になることがあります。
Select-String -Path "C:\logs\app.log" -Pattern "[ERROR]" -SimpleMatch文字列を直接パイプで検索する
ファイルだけでなく文字列を直接 `Select-String` に渡して検索することもできます。簡単な動作確認やコマンドの出力結果をそのまま検索したい場合に便利です。
"hello world" | Select-String "world"別コマンドの結果から特定の文字列を探す使い方もできます。
ipconfig | Select-String "IPv4"このようにパイプラインと組み合わせることでファイル検索だけでなくコマンド出力のフィルタリングにも活用できます。
Get-Contentと組み合わせてリアルタイムで監視する
Get-Contentの-Waitオプションと組み合わせるとファイルを監視しながら新しい行が追加されるたびにリアルタイムで検索できます。Linuxのtail -f | grep *****に相当するイメージです。
Get-Content -Path "C:\logs\app.log" -Wait | Select-String -Pattern "ERROR"動作確認中やデプロイ直後の監視などに向いています。この場合はGet-Contentが出力した内容に対して文字列検索を行っているのでSelect-String側に-Pathは不要です。
Get-Content -Waitでのリアルタイム監視については下記で詳しく解説しています。


よく使う実践パターン
特定フォルダでPowerShellを素早く開く方法は下記で解説しています。


ログファイルから「ERROR」だけ抽出する
Select-String -Path "C:\logs\app.log" -Pattern "ERROR"行番号と内容だけを取り出したい場合は以下のように書けます。
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" | Select-Object LineNumber, LineSelect-Stringの出力オブジェクトには以下のプロパティが含まれています。
| プロパティ | 内容 |
|---|---|
LineNumber | 一致した行番号。 |
Line | 一致した行の内容。 |
Filename | ファイル名。 |
Path | ファイルのフルパス。 |
Matches | 正規表現でマッチした箇所の詳細情報。 |
複数ファイルを一括検索する
ワイルドカードを使うと複数ファイルをまとめて検索できます。
Select-String -Path "C:\logs\*.log" -Pattern "ERROR"PowerShell 7以降では-Pathにワイルドカードを指定してもサブフォルダは検索されないため、サブフォルダも含めて再帰的に検索する場合はGet-ChildItemと組み合わせます。
Get-ChildItem -Path "C:\logs" -Recurse -Filter "*.log" | Select-String -Pattern "ERROR"-Recurseをつけることでサブフォルダ以下もまとめて対象にできます。PowerShell 5.1環境でも同じ書き方で安定して動作します。
Get-ChildItemで取得した複数ファイルの作成日時や更新日時をまとめて変更したい場合はこちらで解説しています。


検索結果を別ファイルに出力する
結果をテキストファイルに保存したい場合はOut-Fileを使います。
Select-String -Path "C:\logs\*.log" -Pattern "ERROR" | Out-File -FilePath "C:\logs\error_report.txt"CSV形式でExcelに取り込みたい場合はこちらが便利です。
Select-String -Path "C:\logs\*.log" -Pattern "ERROR" |
Select-Object Filename, LineNumber, Line |
Export-Csv -Path "C:\logs\error_report.csv" -NoTypeInformation -Encoding UTF8Windows PowerShell 5.1では-NoTypeInformationを省略するとCSVの先頭に型情報が入ります。PowerShell 6以降は型情報を出力しないのが既定ですが、5.1との互換性を考えると指定したままで問題ありません。
抽出結果をCSVとして保存した後に列の追加や再読み込みまで行う場合はImport-CsvとExport-Csvの基本も押さえておくと扱いやすくなります。


よくある質問
まとめ
- PowerShellでgrepに相当するのは
Select-Stringコマンドレットだよ。 - デフォルトで正規表現が使えて大文字・小文字の区別もオプション一つで切り替えられるよ。
Get-Content -Waitと組み合わせるとtail -f | grep相当のリアルタイム監視もできるよ。Get-ChildItem -Recurseとパイプでつなぐと複数フォルダをまとめて検索できるよ。- 結果は
Export-CsvでCSV出力すればそのままExcelで開いて分析できるよ。
文字列検索と組み合わせて使えるログ監視やCSV操作などはPowerShellまとめから目的別に探せます








