PowerShellでgrepする方法【Select-Stringで文字列検索】

PowerShellのアイキャッチ

MacやLinuxに慣れているとWindowsでもgrepを打ちたくなることってありますよね。ログファイルから「ERROR」だけ拾いたいとか、大量テキストから特定の文字列を探したいとか、SEや開発者であれば日常的な場面かと思います。

PowerShellにはSelect-Stringというコマンドレットがあり、grepとほぼ同じことが実現できます。デフォルトで正規表現に対応しているので慣れてしまえばgrepより柔軟に使えるケースもあります。

この記事ではSelect-Stringの基本的な使い方から実践的なパターンまでを解説します。

目次

この記事でわかること

  • PowerShellでgrepに相当するコマンドレットが何か。
  • Select-Stringの基本構文と主要オプション。
  • 正規表現・大文字小文字の区別など検索のカスタマイズ方法。
  • Get-Contentと組み合わせたリアルタイム監視のやり方。
  • ログ抽出・複数ファイル検索・CSV出力などの実践パターン。

PowerShellでgrepに相当するコマンドとは

PowerShellでgrepに相当するのがSelect-Stringコマンドレットです。

ファイルや文字列の中から特定のパターンに一致する行を抽出してくれます。デフォルトで正規表現に対応しており、grepのように-Eオプションを別途つける必要がない点はちょびっとだけ便利かな~と思います。

なお、PowerShellにgrepという名前のエイリアスは存在しません。Windowsのfindstrコマンドと混同しやすいですがSelect-Stringのほうが機能が豊富でPowerShellらしい書き方ができます。

コマンド環境正規表現パイプ対応
grepLinux / macOS
findstrWindows(コマンドプロンプト)△(限定的)
Select-StringPowerShell(Windows / macOS / Linux)

Select-StringはPowerShell 5.1・7系いずれでも使えます。ただしPowerShell 5.1はWindows専用、7系はLinux・macOSでも動作する点が異なります。

PowerShellのコマンド全般についてはこちらもあわせてどうぞ。

Select-Stringの基本構文

コマンド
Select-String -Path <ファイルパス> -Pattern <検索パターン>

よく使うオプションは以下のとおりです。

オプション説明
-Path検索対象のファイルパスを指定する。ワイルドカード(*)使用可。
-Pattern検索する文字列または正規表現パターンを指定する。
-CaseSensitive大文字・小文字を区別して検索する(デフォルトは区別しない)。
-NotMatchパターンに一致しない行を抽出する(grepの-vに相当)。
-SimpleMatch正規表現を使わずリテラル文字列として検索する。
-List一致する行が見つかった最初のファイル名だけを返す。
-Quiet一致したかどうかをTrue/Falseで返す。スクリプトの条件分岐に使いやすい。

基本的な使い方

ファイルから文字列を検索する

もっともシンプルな使い方です。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "ERROR"
PowerShell – 実行結果
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を追加します。

PowerShell
# 「error」は引っかからず「ERROR」だけ検索する
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" -CaseSensitive

逆にオプションなしで使えばerrorErrorERRORをまとめて拾えるということですね。

正規表現で検索する(-Pattern)

-Patternは正規表現をそのまま受け付けます。

例:「ERROR」または「WARN」を含む行を抽出する

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "ERROR|WARN"

例:タイムスタンプ付きの行だけを抽出する

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "\d{4}-\d{2}-\d{2}"

[(.などの記号を文字としてそのまま検索したい場合は-SimpleMatchを使うかバックスラッシュでエスケープすると確実です。

Get-Contentと組み合わせてリアルタイムで監視する

Get-Content-Waitオプションと組み合わせるとファイルを監視しながら新しい行が追加されるたびにリアルタイムで検索できます。Linuxのtail -f | grep *****に相当するイメージです。

PowerShell
Get-Content -Path "C:\logs\app.log" -Wait | Select-String -Pattern "ERROR"

動作確認中やデプロイ直後の監視などに向いています。この場合はGet-Contentが出力した内容に対して文字列検索を行っているのでSelect-String側に-Pathは不要です。

Get-Content -Waitでのリアルタイム監視については下記で詳しく解説しています。

よく使う実践パターン

ログファイルから「ERROR」だけ抽出する

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "ERROR"

行番号と内容だけを取り出したい場合は以下のように書けます。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "ERROR" | Select-Object LineNumber, Line

Select-Stringの出力オブジェクトには以下のプロパティが含まれています。

プロパティ内容
LineNumber一致した行番号。
Line一致した行の内容。
Filenameファイル名。
Pathファイルのフルパス。
Matches正規表現でマッチした箇所の詳細情報。

複数ファイルを一括検索する

ワイルドカードを使うと複数ファイルをまとめて検索できます。

PowerShell
Select-String -Path "C:\logs*.log" -Pattern "ERROR"

PowerShell 7以降では-Pathにワイルドカードを指定してもサブフォルダは検索されないため、サブフォルダも含めて再帰的に検索する場合はGet-ChildItemと組み合わせます。

PowerShell
Get-ChildItem -Path "C:\logs" -Recurse -Filter "*.log" | Select-String -Pattern "ERROR"

-Recurseをつけることでサブフォルダ以下もまとめて対象にできます。PowerShell 5.1環境でも同じ書き方で安定して動作します。

検索結果を別ファイルに出力する

結果をテキストファイルに保存したい場合はOut-Fileを使います。

PowerShell
Select-String -Path "C:\logs*.log" -Pattern "ERROR" | Out-File -FilePath "C:\logs\error_report.txt"

CSV形式でExcelに取り込みたい場合はこちらが便利です。

PowerShell
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の先頭行に型情報が入るので忘れずに。

特定フォルダでPowerShellを素早く開く方法は下記で解説しています。

Q&A

grepコマンドはPowerShellで使える?

PowerShell単体では使えません。ただしGit for WindowsやWSL(Windows Subsystem for Linux)を入れている環境ではそちらのgrepが呼び出せる場合があります。純粋なPowerShell環境ではSelect-Stringを使うのが正解です。

Select-Stringとfindstrの使い分けは?

コマンドプロンプト(cmd.exe)を使う場面ではfindstrが手軽ですが正規表現の対応が限定的です。PowerShellを使える環境であればSelect-Stringのほうが柔軟で出力のカスタマイズもしやすいです。

一致した部分だけを取り出すことはできる?

-Patternに正規表現のキャプチャグループを使いMatchesプロパティを参照すると一致箇所のみを抽出できます。

PowerShell 5.1と7系で動作に違いはある?

基本的なSelect-Stringの動作はほぼ同じです。PowerShell 7系はLinux・macOSでも動作しGet-ChildItemの一部の挙動が異なる場合があります。5.1環境では再帰検索にGet-ChildItem -Recurseとの組み合わせが安定しています。

PowerShellのバージョン確認方法や更新手順はこちらで解説しています。

まとめ

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