MacやLinuxを使い慣れているとWindows環境でもついつい grep を打ちたくなることってありますよね。 ログファイルから「ERROR」だけ拾いたいとか、大量のテキストから特定の文字列を探したいとか、そういう場面はSEや開発者であれば日常茶飯事かと思います。
PowerShellには Select-String というコマンドレットがあり、grepとほぼ同じことが実現できます。 正規表現にも対応しているので慣れてしまえばgrepよりも柔軟に使えるケースもあります。
この記事では Select-String の基本的な使い方から実践的なパターンまでを解説します。
この記事でわかること
- PowerShellでgrepに相当するコマンドレットが何か。
Select-Stringの基本構文と主要オプション。- 正規表現や大文字・小文字を区別しない検索の方法。
Get-Contentと組み合わせたリアルタイム検索のやり方。- ログ抽出・複数ファイル検索・結果ファイル出力などの実践パターン。
Linuxのgrepに相当するPowerShellのコマンドとは
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の基本構文
Select-String -Path <ファイルパス> -Pattern <検索パターン>
よく使うオプションをまとめると以下のとおりです。
| オプション | 説明 |
|---|---|
-Path | 検索対象のファイルパスを指定する。ワイルドカード(*)使用可。 |
-Pattern | 検索する文字列または正規表現パターンを指定する。 |
-CaseSensitive | 大文字・小文字を区別して検索する(デフォルトは区別しない)。 |
-NotMatch | パターンに一致しない行を抽出する(grepの -v に相当)。 |
-SimpleMatch | 正規表現を使わずリテラル文字列として検索する。 |
-List | 一致する行が見つかった最初のファイル名だけを返す。 |
-Quiet | 一致したかどうかをTrue/Falseで返す。スクリプトの条件分岐に使いやすい。 |
基本的な使い方
ファイルから文字列を検索する
もっともシンプルな使い方です。
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 は正規表現をそのまま受け付けます。
例:「ERROR」または「WARN」を含む行を抽出する
Select-String -Path "C:\logs\app.log" -Pattern "ERROR|WARN"
例:タイムスタンプ付きの行だけを抽出する(数字4桁-数字2桁-数字2桁の形式)
Select-String -Path "C:\logs\app.log" -Pattern "\d{4}-\d{2}-\d{2}"
[・]・(・)・. などの記号を文字としてそのまま検索したい場合は -SimpleMatch を使うか、バックスラッシュでエスケープすると確実です。
Get-Contentと組み合わせてリアルタイムで検索する
Get-Content の -Wait オプションと組み合わせると、ファイルを監視しながら新しい行が追加されるたびにリアルタイムで検索できます。 tail -f | grep ***** に相当するイメージです。
Get-Content -Path "C:\logs\app.log" -Wait | Select-String -Pattern "ERROR"
ログファイルをリアルタイムで監視して「ERROR」が出たら確認する、という使い方ができます。 動作確認中やデプロイ直後の監視などに向いています。
この場合Get-Content で出力した内容に対して文字列検索を行っているので、Select-String側に-Path は不要です。
Get-Content -Wait の詳しい使い方や -Tail オプションなどこちらで解説しています。
よく使う実践パターン
ケース1: ログファイルから「ERROR」だけ抽出する
Select-String -Path "C:\logs\app.log" -Pattern "ERROR"
行番号と一致した内容だけを取り出したい場合は以下のように書けます。
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" | Select-Object LineNumber, Line
| プロパティ | 内容 |
|---|---|
LineNumber | 一致した行番号。 |
Line | 一致した行の内容(前後の空白は除去されない)。 |
Filename | ファイル名。 |
Path | ファイルのフルパス。 |
Matches | 正規表現でマッチした箇所の詳細情報。 |
ケース2: 複数ファイルを一括検索する
ワイルドカードを使うと複数ファイルをまとめて検索できます。
同一フォルダ内のすべての .log ファイルを検索する
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を開く方法を知っておくと作業がスムーズです。
ケース3: 検索結果を別ファイルに出力する
結果をテキストファイルに保存したい場合は Out-File または Set-Content を使います。
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 UTF8
-NoTypeInformation をつけないとCSVの先頭行に型情報が入るので忘れずに。
この一連の処理をタスクスケジューラーで定期自動実行すれば、ログ収集〜レポート生成を完全自動化できます。タスクスケジューラーの設定方法はこちらを参照ください。
Q&A
- QgrepコマンドはPowerShellで使える?
- A
PowerShell単体では使えません。ただしGit for WindowsやWSL(Windows Subsystem for Linux)をインストールしている環境では、そちらのgrepが呼び出せることがあります。純粋なPowerShell環境では
Select-Stringを使うのが正解です。
- QSelect-String と findstr の使い分けは?
- A
コマンドプロンプト(cmd.exe)を使う場面では
findstrが手軽ですが、正規表現の対応が限定的です。PowerShellを使える環境であればSelect-Stringのほうが柔軟で出力のカスタマイズもしやすいです。
- Q一致した部分だけを取り出すことはできる?
- A
-Patternに正規表現のキャプチャグループを使いMatchesプロパティを参照すると、一致箇所のみを抽出できます。PowerShellSelect-String -Path "C:\logs\app.log" -Pattern "(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})" | ForEach-Object { $_.Matches[0].Value }
- QPowerShell 5.1と7系で動作に違いはある?
- A
基本的な
Select-Stringの動作はほぼ同じです。ただしPowerShell 7系はLinux・macOSでも動作し、Get-ChildItemの一部の挙動が異なる場合があります。WindowsのPowerShell 5.1環境では再帰検索にGet-ChildItem -Recurseとの組み合わせが安定しています。PowerShell 7系への移行を検討している方はこちらもどうぞ。
まとめ
- PowerShellでgrepに相当するのは
Select-Stringコマンドレットだよ。 - デフォルトで正規表現が使えて大文字・小文字の区別もオプション一つで切り替えられるよ。
Get-Content -Waitと組み合わせるとtail -f | grep相当のリアルタイム監視もできるよ。Get-ChildItem -Recurseとパイプでつなぐと複数フォルダをまとめて検索できるよ。- 結果は
Export-CsvでCSV出力すれば、そのままExcelで開いて分析できるよ。
Select-Stringをきっかけに「PowerShellをもっと体系的に学びたい」という方には、パイプラインの仕組みやオブジェクト処理の考え方まで丁寧に解説してくれる『PowerShell実践ガイドブック』がおすすめです。「なぜそう動くのか」まで理解したい方に向いています。
Select-String以外のPowerShellコマンドも学びたい方はこちらのまとめもどうぞ。



