Select-String:PowerShell における grep 機能

投稿者: Adam Bertram 投稿日: 2018年8月19

PowerShell コードを書くときに、単一の文字列またはテキストファイル全体の中でテキストを検索したい場合は、どうすればいいでしょうか?Unix/Linux を使ったことがある人は、多分よく使われる grep ユーティリティはご存知でしょう。grep ユーティリティはオプションつきでテキスト検索できますが、このユーティリティは Windows には存在しません。万事休すでしょうか?いいえ、Select-String コマンドレットがあります。

多くの従業員の名前と住所を含む大きな文字列があるとしましょう。この文字列の構造は一般的なものではないので、すべての従業員名を取り出すにはテキスト解析が必要になります。どうすればいいでしょうか?まず、ここで例として使用する文字列を見てみましょう。

||Adam Bertram|| 2122 Acme Ct, Atlantic City, NJ
--||Joe Jonesy||-- 555 Lone St, Las Vegas, NV
==|Suzie Shoemaker|== 6783 Main St, Los Angelas, CA

この文字列に $employees という変数名を割り当てます。文字列から従業員の名前を取得するために、Select-String の右に、シンタックスを並べます。まず、Pattern パラメータを使って従業員名の1つを静的に検索してみましょう。

PS> $employees | Select-String -Pattern 'Adam Bertram'

||Adam Bertram|| 2122 Acme Ct, Atlantic City, NJ
--||Joe Jonesy||-- 555 Lone St, Las Vegas, NV
==|Suzie Shoemaker|== 6783 Main St, Los Angelas, CA

Select-String は何かを返してきました。検索に失敗したら何も返さないので、何かを返したということは一致するものが見つかったことを意味します。ですが、返ってきたものは、文字列全体です。なぜでしょうか?その理由は、Select-String が文字列全体を1個の最小単位として解析したからです。そこで、この文字列を一行ずつの異なる文字列に分割する方法を考えなければなりません。各従業員のレコードはそれぞれ別の行にあるので、改行文字(`n)のところで分割することができます。

PS> $employees = $employees -split "`n"
PS> $employees | Select-String -Pattern 'Adam Bertram'

||Adam Bertram|| 2122 Acme Ct, Atlantic City, NJ

検索結果として正しい一行だけが返ってきました。ちょっと見込みが立ってきました。次に、すべての従業員の情報を獲得できるよう指定する必要があります。そのためには、それぞれの行に共通したパターンがあるかを見てみます。各従業員の名前は縦棒(|)で囲まれているようです。Select-String の Pattern パラメータでこのパターンを使用できます。また、各従業員の名と姓はスペースで区切られているので、これも考慮に入れることができます。

このパターンは、Select-String の Pattern パラメータで、問題なく使える正規表現で表示するよう指定できます。

PS> $employees | Select-String -Pattern '\|\w+ \w+\|'

||Adam Bertram|| 2122 Acme Ct, Atlantic City, NJ
--||Joe Jonesy||-- 555 Lone St, Las Vegas, NV
==|Suzie Shoemaker|== 6783 Main St, Los Angelas, CA

今度は、Select-String は正規表現を使用して各行を返すようになりました。次に、それぞれの社員名を解析する必要があります。現時点では、住所の情報は必要ありません。社員名の解析のために、Select-String が返すマッチしたオブジェクトの Matches プロパティを参照します。

PS> $employees | Select-String -Pattern '\|\w+ \w+\|' | foreach {$_.Matches}

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 1
Length   : 14
Value    : |Adam Bertram|

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 3
Length   : 12
Value    : |Joe Jonesy|

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 2
Length   : 17
Value    : |Suzie Shoemaker|

もう少しです!Value プロパティに必要な従業員名が含まれていることがわかりました。ですが、パイプ文字(縦棒)に囲まれています。これは、正規表現を使った検索でパイプ文字に囲まれたものを指定したためです。検索にはパイプ文字を含める必要がありますが、検索結果としてはパイプ文字を含まない文字列が欲しいところです。どうするべきでしょうか?1つの方法は、正規表現グループを使用することです。正規表現グループは、返してほしい検索結果をカッコで囲んで表現します。この場合、従業員の名と姓を表す正規表現文字列をカッコで囲んで、もう一度やり直してみましょう。

PS> $employees | Select-String -Pattern '\|(\w+ \w+)\|' | foreach {$_.Matches}

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 1
Length   : 14
Value    : |Adam Bertram|

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 3
Length   : 12
Value    : |Joe Jonesy|

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 2
Length   : 17
Value    : |Suzie Shoemaker|

あれぇ、Value はまだパイプ文字を含んでいますね。でも、ちょっと Groups プロパティを見ていただけますか?以前の {0} ではなく、{0, 1} と表示されています。これは、Select-String がグループを認識したことを意味します。このグループの各要素を表示するには、foreach ループを使ってそれぞれに適用します。Groups プロパティは配列なので、1つの要素ごとに、カッコでくくられたパイプ文字のない部分をその Value プロパティとして表示するようにします。

PS> $employees | Select-String -Pattern '\|(\w+ \w+)\|' | foreach {$_.Matches.Groups[1].Value}
Adam Bertram
Joe Jonesy
Suzie Shoemaker

これで文字列から各従業員の名前を取り出すことができました!Select-String はもっといろいろなことが可能なので、検索してチェックしてみてください。


Adam Bertram
Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.
著者が作成したブログ

関連タグ

関連記事

PowerShell を使用した再起動時間の測定
エンタープライズ環境には、通常、様々な Windows オペレーティングシステム、ハードウェア、そしてもちろん数多くのソフトウェアがあります。マシンは、多くの場合、グループポリシーと SCCM、あるいは Chef や Puppet などの他の新しい方法で設定され、管理されます。Windows コンピュータに問題がないかどうかをチェックするための1つの指標として、起動にかかる時間があります。
何百ものサーバーからの Windows イベントログを検索する方法
トラブルシューティングや潜在的なセキュリティ侵害の調査を開始するときは、取り掛かりとして、まず Windows のイベントログをチェックすることが多いと思います。
PowerShellを使用してWindowsユーザーをリモートからログオフ
エンドユーザーがずっと自分のコンピュータにログインしている場合、必要があれば簡単にリモートからエンドユーザーをログオフすることができます。メンテナンスをしようとしているときなどには、知っておくと特に便利です。
MOVEit 2018 の REST API で PowerShell を使う
MOVEit の利用形態として、MOVEit コンソールや Web インタフェースからログインして日々の管理業務を行ったり、1回限りのワークフローを設定して操作する作業は理にかなっており、首尾よくいきます。一方、MOVEit Automation の自動化を活用したいケースもあります。
PowerShell: スクリプトを超えて広がる可能性
PowerShell と聞いて、頭に浮かぶのは何でしょうか?スクリプト?おそらくそうでしょう。もちろん、PowerShell の主要な機能はスクリプティングですが、もう一つ、優れた枠組みとしてのシェルという特性があります。
Prefooter Dots
Subscribe Icon

Latest Stories in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

The specified form no longer exists or is currently unpublished.