本記事にはアフィリエイトリンクを含みます。Amazonのアソシエイトとして収益を得る場合があります。

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

PowerShellのアイキャッチ PowerShell
PowerShell

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

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

Select-Stringの基本構文

PowerShell

よく使うオプションをまとめると以下のとおりです。

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

基本的な使い方

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

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

PowerShell

実行すると、一致した行がこのように表示されます。

PowerShell – 実行結果

出力は ファイル名:行番号:行の内容 という形式になっています。 どのファイルの何行目にあるかが一目でわかるので、ログ調査のときに重宝します。

大文字・小文字を区別して検索する(-CaseSensitive)

Select-String はデフォルトで大文字・小文字を区別しません。 区別して検索したい場合は -CaseSensitive を追加します。

PowerShell

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

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

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

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

PowerShell

例:タイムスタンプ付きの行だけを抽出する(数字4桁-数字2桁-数字2桁の形式)

PowerShell

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

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

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

PowerShell

ログファイルをリアルタイムで監視して「ERROR」が出たら確認する、という使い方ができます。 動作確認中やデプロイ直後の監視などに向いています。

この場合Get-Content で出力した内容に対して文字列検索を行っているので、Select-String側に-Path は不要です。

よく使う実践パターン

ケース1: ログファイルから「ERROR」だけ抽出する

PowerShell

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

PowerShell
プロパティ内容
LineNumber一致した行番号。
Line一致した行の内容(前後の空白は除去されない)。
Filenameファイル名。
Pathファイルのフルパス。
Matches正規表現でマッチした箇所の詳細情報。

ケース2: 複数ファイルを一括検索する

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

同一フォルダ内のすべての .log ファイルを検索する

PowerShell

サブフォルダも含めて再帰的に検索する

PowerShell 7以降では -Path にワイルドカードを使ってもサブフォルダは検索されないため Get-ChildItem と組み合わせます。

PowerShell

-Recurse をつけることでサブフォルダ以下もまとめて対象にできます。

ケース3: 検索結果を別ファイルに出力する

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

PowerShell

CSV形式で保存してExcelで開きたい場合はこちらが便利です。

PowerShell

-NoTypeInformation をつけないとCSVの先頭行に型情報が入るので忘れずに。

Q&A

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

PowerShell単体では使えません。ただしGit for WindowsWSL(Windows Subsystem for Linux)をインストールしている環境では、そちらのgrepが呼び出せることがあります。純粋なPowerShell環境では Select-String を使うのが正解です。

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

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

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

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

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

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

まとめ

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

当ブログの内容はできる限り正確な情報を提供するよう努めていますが、利用にあたっては自己責任でお願いいたします。
掲載内容に基づく操作・設定などによって生じたトラブルや損害について、当サイトは一切の責任を負いません。
タイトルとURLをコピーしました