PowerShellでgrepする方法|Select-Stringの使い方と実践例

当ページのリンクには広告が含まれています。
PowerShellのSelect-Stringでエラーログを検索する画面と使い方・オプションを示したアイキャッチ画像

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らしい書き方ができます。

コマンド環境正規表現パイプ対応
grepLinux / macOS○○
findstrWindows(コマンドプロンプト)△(限定的)○
Select-StringPowerShell(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公式ドキュメントも参照してください。

基本的な使い方

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

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

PowerShell
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を追加します。

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

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

正規表現・複数条件で検索する(-Pattern)

-Patternは既定で正規表現として解釈されます。複数条件を指定する場合OR検索では|、AND検索ではSelect-Stringをパイプでつなぎます。-NotMatchを使うと指定したパターンを含まない行を抽出できます。

PowerShell
# 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

タイムスタンプのように形式が決まっている文字列も正規表現で検索できます。

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

文字列で検索する(-SimpleMatch)

正規表現ではなく文字列をそのまま検索したい場合は-SimpleMatchを使います。

たとえば[や]などの正規表現で特別な意味を持つものは、そのまま検索すると意図しない結果になることがあります。

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

文字列を直接パイプで検索する

ファイルだけでなく文字列を直接 `Select-String` に渡して検索することもできます。簡単な動作確認やコマンドの出力結果をそのまま検索したい場合に便利です。

PowerShell
"hello world" | Select-String "world"

別コマンドの結果から特定の文字列を探す使い方もできます。

PowerShell
ipconfig | Select-String "IPv4"

このようにパイプラインと組み合わせることでファイル検索だけでなくコマンド出力のフィルタリングにも活用できます。

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でのリアルタイム監視については下記で詳しく解説しています。

よく使う実践パターン

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

ログファイルから「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環境でも同じ書き方で安定して動作します。


Get-ChildItemで取得した複数ファイルの作成日時や更新日時をまとめて変更したい場合はこちらで解説しています。

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

結果をテキストファイルに保存したい場合は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

Windows PowerShell 5.1では-NoTypeInformationを省略するとCSVの先頭に型情報が入ります。PowerShell 6以降は型情報を出力しないのが既定ですが、5.1との互換性を考えると指定したままで問題ありません。


抽出結果をCSVとして保存した後に列の追加や再読み込みまで行う場合はImport-CsvとExport-Csvの基本も押さえておくと扱いやすくなります。

よくある質問

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

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

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

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

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

できます。1行に複数の一致箇所がある場合は-AllMatchesを付け、各MatchInfoオブジェクトのMatches.Valueを取り出します。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "ERROR\d+" -AllMatches |
    ForEach-Object { $_.Matches.Value }

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

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

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

PowerShellで日本語ログが文字化けしてしまう。

PowerShellのバージョンと対象ファイルの文字コードが一致していない可能性があります。Select-StringはBOMのないファイルをUTF-8として扱うため、Shift_JIS(CP932)のログでは文字化けや検索漏れが起こることがあります。

PowerShell 7系ではCP932をコードページ番号で指定できます。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "エラー" -Encoding 932

Windows PowerShell 5.1では932やshift_jisを-Encodingへ直接指定できません。日本語版WindowsでシステムのANSIコードページがCP932の場合はDefaultを指定します。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "エラー" -Encoding Default

UTF-8のログを検索する場合は、PowerShell 5.1・7系ともに次のように指定できます。

PowerShell
Select-String -Path "C:\logs\app.log" -Pattern "エラー" -Encoding UTF8

Defaultが表す文字コードはWindowsのシステム設定に依存します。ファイルの文字コードとPowerShellのバージョンを確認してから指定してください。

PowerShell 5.1で利用できる指定値と、PowerShell 6.2以降でコードページ番号・名称を指定できる仕様はMicrosoftの文字コード解説で確認できます。

まとめ

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

文字列検索と組み合わせて使えるログ監視やCSV操作などはPowerShellまとめから目的別に探せます

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次