Select-Stringの使い方:ファイルや出力結果から文字列を検索する
Select-String コマンドレットを使用すると、ファイルや文字列の中から指定した文字列を検索することができます。正規表現を使った高度な検索が可能で、複数のファイルをまとめて検索することもできます。パイプラインと組み合わせることで、コマンドの出力結果から特定の文字列を検索することも可能です。ここでは PowerShell における Select-String コマンドレットの使い方について解説します。
目次
Select-Stringコマンドレットの書式
Select-String コマンドレットは、ファイルや文字列の中から指定した文字列を検索するためのコマンドレットです。 Select-String コマンドレットの書式は次の通りです。
Select-String [-Pattern] <String[]> [-Path] <String[]> [-Culture <String>] [-SimpleMatch] [-CaseSensitive] [-Quiet] [-List] [-NoEmphasis] [-Include <String[]>] [-Exclude <String[]>] [-NotMatch] [-AllMatches] [-Encoding <Encoding>] [-Context <Int32[]>] [<CommonParameters>]
Select-String はエイリアスとして sls が定義されています。
sls -> Select-String
Select-String を使ってファイルに内容を検索するには次の書式を使用します。
Select-String -Pattern 検索パターン -Path ファイルのパス
-Pattern および -Path は省略可能なので、通常は次のように実行します。
Select-String 検索パターン ファイルのパス
検索パターンには正規表現が使用できます。(正規表現については「正規表現入門」を参照されてください)。
それでは実際に試してみます。検索の対象となる c:\tmp\file\gadget.txt には次のようなテキストを入力しています。
04/05 SmartPhone Red 2 04/06 Mouse White 3 04/07 PC Black 1 04/07 Mouse Red 2 04/08 Tablet Black 3 04/08 SmartPhone White 1 04/09 Keyboard Silver 2 04/10 PC Black 1 04/11 Monitor White 3 04/12 Mouse Black 2
最初に "SmartPhone" が含まれる行を検索します。次のように実行してください。
Select-String "SmartPhone" c:\tmp\file\gadget.txt
次のように画面に表示されました。
検索パターンと一致した行があった場合、「ファイル名:行番号:該当する行の内容」の形式で表示されます。今回は 2 行見つかっています。それぞれの行で、マッチした部分が強調表示されています。
次に "PC" または "Tablet" が含まれる行を検索します。次のように実行してください。
Select-String "PC|Tablet" c:\tmp\file\gadget.txt
※ | は「または(OR)」を意味する正規表現です。
実行結果は次のようになりました。
複数のファイルを対象に検索する
Select-String では複数のファイルを対象に検索することができます。
ファイルを個々に指定する場合は、カンマ(,)で区切って記述してください。
Select-String 検索パターン ファイルのパス1, ファイルのパス2, ...
ワイルドカードのアスタリスク(*)を使用することもできます。例えば同じディレクトリの拡張子が .txt のファイルを対象とする場合は次のように記述します。
Select-String 検索パターン ファイルのパス\*.txt
それでは実際に試してみます。次のように実行してください。
Select-String "Black" c:\tmp\file\*.txt
次のように画面に表示されました。
現在 c:\tmp\file には拡張子が .txt のファイルが 2 つあり、2 つのファイルの中から、検索パターンに一致した行が表示されました。
サブディレクトリも再帰的に検索する
サブディレクトリも含めて再帰的に検索を行いたい場合は、 Get-ChildItem コマンドレットを利用して次のように行います。
Get-ChildItem ファイルのパス -Recurse | Select-String -Pattern 検索パターン
パイプ(|)を使用することで、Get-ChildItem の結果を Select-String に渡しています。
それでは実際に試してみます。次のように実行してください。
Get-ChildItem c:\tmp\file -Recurse | Select-String "Black"
Get-ChildItem -Recurse を使用することで、サブディレクトリ内のファイルも含めて検索することができます。
次のように画面に表示されました。
指定したパスにサブディレクトリが含まれる場合は、サブディレクトリの中のファイルも再帰的に検索を行いました。
単純な文字列として検索する
Select-String ではデフォルトで正規表現を使って検索を行いますが、 -SimpleMatch オプションを使用すると、正規表現ではなく単純一致で検索できます。
入力した文字列をそのままの形で検索するため、「.」や「*」などの記号もそのまま文字として扱われます。
Select-String 検索文字列 ファイルのパス -SimpleMatch
正規表現のパターンではなく、入力した検索文字列と単純に一致するかどうかで検索します。大量のデータを対象に検索する場合に、正規表現を使用する場合より、高速で行える場合が多く、また意図しない値をマッチしてしまう可能性も低くなります。
それでは実際に試してみます。次のように実行してください。
Select-String "04/08" c:\tmp\file\gadget.txt -SimpleMatch
次のように画面に表示されました。
大文字と小文字を区別する
Select-String では、正規表現を使用する場合でも、-SimpleMatch を指定した単純一致の場合でも、大文字と小文字は区別されません。例えば "Blue" は "BLUE" や "blue" にも一致します。
大文字と小文字を区別して検索する場合には -CaseSensitive オプションを使用します。
Select-String 検索文字列 ファイルのパス -CaseSensitive
それでは試してみます。検索の対象となる c:\tmp\file\address.txt には次のようなテキストを入力しています。
Yamada Tokyo 24 Suzuki Osaka 33 Endou tokyo 21 Nishida Hyogo 27 Honda TOKYO 35 Kimura Tokyo 28 Etou osaka 31
最初の -CaseSensitive オプションを指定せずに、次のように実行しました。
Select-String "Tokyo" c:\tmp\file\address.txt
次のように画面に表示されました。
PS C:\code\powershell> Select-String "Tokyo" c:\tmp\file\address.txt C:\tmp\file\address.txt:1:Yamada Tokyo 24 C:\tmp\file\address.txt:3:Endou tokyo 21 C:\tmp\file\address.txt:5:Honda TOKYO 35 C:\tmp\file\address.txt:6:Kimura Tokyo 28
検索したパターンは "Tokyo" ですが、 "tokyo" や "TOKYO" にもマッチしているのが確認できます。
次に -CaseSensitive オプションを指定して、次のように実行しました。
Select-String "Tokyo" c:\tmp\file\address.txt -CaseSensitive
次のように画面に表示されました。
PS C:\code\powershell> Select-String "Tokyo" c:\tmp\file\address.txt -CaseSensitive C:\tmp\file\address.txt:1:Yamada Tokyo 24 C:\tmp\file\address.txt:6:Kimura Tokyo 28
今回は "Tokyo" とだけマッチし、 "TOKYO" や "tokyo" とはマッチしませんでした。このように -CaseSensitive オプションを使用することで、大文字と小文字の区別をして検索することができます。
なお正規表現を使用する場合は、 -CaseSensitive オプションを使用しなくても、例えば次のように (?-i) をパターンの前に記述することで大文字と小文字の区別をつけるように指定できます。
Select-String "(?-i)Tokyo" c:\tmp\file\address.txt
※ (?-i) は正規表現において「大文字と小文字を区別する」ことを指定する記法です。
実際に実行すると、次のように画面に表示されました。
PS C:\code\powershell> Select-String "(?-i)Tokyo" c:\tmp\file\address.txt C:\tmp\file\address.txt:1:Yamada Tokyo 24 C:\tmp\file\address.txt:6:Kimura Tokyo 28
それに対して -SimpleMatch を使用している場合は正規表現が使えないため、大文字と小文字を区別するには -CaseSensitive オプションを併用する必要があります。
検索に一致した行の前後の行を一緒に表示する
-Context オプションを使用すると、検索に一致した行の前後の行を一緒に表示することができます。
Select-String 検索文字列 ファイルのパス -Context 行数 Select-String 検索文字列 ファイルのパス -Context 前の行数, 後の行数
例えば前の行数に 2、後の行数に 3 を指定すると、検索に一致した行を含めて、前 2 行と後 3 行の合計 6 行が表示されます。行数を 1 つだけ指定した場合は、前後に同じ行数が表示されます。複数の行が表示されますが、一致した行は、先頭に > が付いて表示されるため、どの行が検索条件に一致したのかが分かります。
このオプションを使用すると、前後の情報をまとめて確認できるため、ログ解析やトラブルシューティングで非常に役立ちます。
それでは実際に試してみます。次のように実行してください。
Select-String "Chair Black" c:\tmp\file\*.txt -Context 1,2
次のように画面に表示されました。
例えば検索に一致したコードの前後を同時に見ることで、たまたま一致したものなのか、それとも目的のものなのかの判断がしやすかったり、前後でどのような処理が行われているのかを一度に確認できます。また検索に一致したログの前後を同時に見ることで、同時に他のエラーなどが発生していないかなどを合わせて確認できます。
検索に一致したかどうかを真か偽で返す
Select-String を使って検索を行うと、通常は一致した行やそのファイルに関する情報を持つ MatchInfo オブジェクトが返されます。
-Quiet オプションを使用すると、検索に一致した場合は $true 、一致しなかった場合は $false を返します。
Select-String 検索文字列 ファイルのパス -Quiet
PowerShell スクリプトなどで、検索に一致したかどうかだけを確認して、処理を分ける場合などに使用されます。結果の詳細を取得せずに真偽値だけを返すため、処理を高速に行うことができます。
では、実際に試してみます。次の PowerShell スクリプトは、指定したディレクトリに含まれる拡張子が(.txt)のファイルに対して、順に "在庫補充" という文字列が含まれているかどうかを調べ、見つかった場合はメッセージを表示するものです。
$path = "c:\tmp\file"
foreach ($file in Get-ChildItem $path -Filter *.txt) {
if (Select-String "在庫補充" $file.FullName -Quiet) {
Write-Host "ファイル名: $($file.Name)"
Write-Host "メッセージ: このファイルには在庫補充の依頼が含まれています。"
}
}
実際に実行してみると、次のように画面に表示されました。
このように -Quiet オプションを使用することで、対象のファイルの中で検索した文字列が一つでも見つかるかどうかを調べることができます。
最初に一致した行だけを取得する
Select-String は通常、ファイル内のすべての一致する行を検索しますが -List オプションを使用すると、各ファイルごとに最初に一致した行だけを取得し、そのファイル内でのそれ以降の検索は行われません。
-List オプションは、検索した文字列が含まれるファイルの情報だけを取得したい場合など、どのファイルに検索文字列が含まれているかを確認したい場合などに便利です。不要な検索を行わないため、処理を高速に行うことができます。
Select-String 検索文字列 ファイルのパス -List
少し似た目的で使用する -Quiet オプションがありますが、-Quiet が真偽値を返すのに対し、-List は一致した行の情報(MatchInfo オブジェクト)を返します。
それでは実際に試してみます。下記のように実行してください。
Select-String "在庫補充" c:\tmp\file\*.txt -List | Select-Object Path
Select-String を使って、指定したディレクトリにあるファイルを順に検索していき、見つかった場合はそのオブジェクトをパイプを使って Select-Object へ渡してパスの情報だけを表示しています。
次のように画面に表示されました。
このように -List オプションを使用することで、対象のファイルの中で最初に見つかった行に関するオブジェクトを取得できます。
ファイルの文字コードを指定する
Select-String では、既定の文字コード(PowerShell 7 では通常 UTF-8(BOMなし))でファイルを読み込んで検索を行います。異なる文字コードが使用されている場合は -Encoding オプションを使用して文字コードを指定します。
Select-String 検索文字列 ファイルのパス -Encoding 文字コード
文字コードとして指定できる値は次の通りです。デフォルトの値は utf8NoBOM です。
ascii ansi bigendianunicode bigendianutf32 oem unicode utf7 utf8 utf8BOM utf8NoBOM utf32
※ utf7 は非推奨です。
また登録済みのコードページの数値を指定したり(-Encoding 932 など)、登録されたコードページの文字列名(-Encoding Shift_JIS など) も使用できます。
ansi を指定した場合は、現在の Windows のシステムロケールに対応した ANSI コードページが使用されます。日本語環境では通常、コードページ 932(Shift_JIS)が使用されます。そのため、 Shift_JIS でファイルを保存する場合は -Encoding オプションの値として ansi を指定するか、コードページの数値である 932 を指定してください。
それでは実際に試してみます。 c:\tmp\file\address.txt ファイルに次のようなテキストを入力しました。文字コードとして Shift_JIS でファイルを保存しています。
山田 一郎 東京都 鈴木 花子 京都府 西村 健吾 千葉県 山崎 隆 東京都 近藤 佐奈 大阪府 吉村 隼人 京都府
最初に文字コードを指定せずに下記のように実行しました。
Select-String "東京都" c:\tmp\file\address.txt
検索と一致する行はなく、画面には何も表示されませんでした。これは、ファイルの文字コードと読み込み時の文字コードが一致していないため、正しく文字列を認識できないことが原因です。
次に対象のファイルで使用されている文字コードを指定して下記のように実行しました。
Select-String "東京都" c:\tmp\file\address.txt -Encoding 932
今度は対象のファイルで正常に検索を行うことができました。
既定の文字コードと異なるファイルを検索する場合は、-Encoding を指定するようにしてください。
-- --
PowerShell における Select-String コマンドレットの使い方について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。