亀の甲羅2

今日もまた朝とく起きて励まなん窓に明るきありあけの月

Where-Object :行の選択、オブジェクトの選択、SQLのWhere句

Where-Object で絞り込む

Powershellのコマンド結果はオブジェクト形式で返却されることが多いが、 そのオブジェクト形式で返ってきた結果の一部だけを取得する方法の実験。
  例えば、以下のようなコマンドレットを実行すると、結果がズラズラと表示される。
これらの1行の情報はオブジェクトのデータを表示している。

> Get-ChildItem

Mode                 LastWriteTime         Length Name                                                                                        
----                 -------------         ------ ----                                                                                        
d-----        2020/09/21      9:33                .android                                                                                    
d-----        2020/09/20     22:39                .AndroidStudio4.0                                                                           
d-----        2018/04/21     22:26                .gimp-2.8                                                                                   
・・・
-a----        2021/06/15     18:03            761 _gvimrc                                                                                     
-a----        2021/06/17     20:04           9117 _viminfo                                                                                    
-a----        2021/06/16     17:39           3542 _vimrc                                                                                      

なので、例えば$aにコマンドレットの結果をオブジェクトの配列として格納して、インデックスでアクセスできる。

> $a = Get-ChildItem

> $a[0]


Mode                 LastWriteTime         Length Name                                                                                        
----                 -------------         ------ ----                                                                                        
d-----        2020/09/21      9:33                .android                                                                                    

> $a[0].Name
.android

そうすると、例えば、Nameがドット(.)から始まるフォルダ、ファイルの情報だけが欲しい・・・なんてことはよくある。

 
 
 

 
 

目次

本文

1. Where-Objectで行選択

Where-Objectコマンドレッドにより任意の条件に合致するオブジェクトだけを絞り込むことができる。 誤解を恐れずイメージだけで言えば、Where-Objectは行選択できる。

例えば、Nameが”.android"の行だけに絞り込みたいなら、こんな感じ。

> Get-ChildItem | Where-Object { $_.Name -eq ".android"}

Mode                 LastWriteTime         Length Name                                                                                        
----                 -------------         ------ ----                                                                                        
d-----        2020/09/21      9:33                .android      

Where-Objectの基本形はこれだけ。

2. 比較演算子

forsenergy.com

ここら辺の比較演算子は、if文を使うときには必ず通ることなので、特に記すべきこともないが、
-likeと-matchだけ深堀りしようと思う。

3. 比較演算子 -like (ワイルドカードを使った比較)

forsenergy.com

ワイルドカードを使った、簡単な条件指定ができる。

ワイルドカード 説明 True False 備考
* 0個以上の文字と一致 a* a、ab、Apple ba、bab、BApple 先頭末尾という概念はあり
? 指定位置の1文字と一致 a? ab、Ap ba、abb、a まず文字数が一致しないとダメ
[ ] 指定範囲の1文字と一致 a[a-c]c aac、abc、acc、aAc ac、adc 文字数一致と範囲の1文字と一致
[ ] 指定された1文字と一致 a[rkq]c arc、akc、aqc、aRc ac、aac 文字数一致と列挙の1文字と一致

※[]内にワイルドカード(*,?)は使えない。記述してもリテラルとして解釈されるようだ。

4. 比較演算子 -match (正規表現を使った比較)

forsenergy.com

docs.microsoft.com

以下、再検証

形式 説明 例(パターン) True False 備考
値が(部分的に)一致すればTrue "bc" "abcd"、"bcd"、"abc" "adc" 部分一致すればTrue
. 任意の 1 文字と一致すればTrue "a..d" "abcd"、"abcdz"、"zabcd" "abd"、"abcz" ワイルドカードの?に似ている
[ ] カギ括弧内の1 文字と一致すればTrue "a[abcdefg]c" "abc"、"agc" "ahc"、"ac"、"abz"
[ ] カギ括弧内の範囲の1 文字と一致すればTrue "a[a-g]c" "abc"、"agc" "ahc"、"ac"、"abz"
[^] カギ括弧内の文字以外の任意の文字と一致すればTrue "a[^abc]c" "adc" "aac"、"abc"、"acc"、"adz"
^ 先頭を表す "^ab" "ab"、"abc" "bb"、"bbc"、"ac"
$ 末尾を表す "yz$" "yz"、"xyz" "yy"、"xyy"、"xz"
* 先行する文字が0個以上 "a*c" "ac"、"aac"、"aaac"、"abc"、"c" ”a”、”aa"、”aad" 部分一致でTrueになる原則、は直前文字が0個以上。 その為”ac”は実質cが一文字でもあればTrue
? 先行する文字が1 個以上(だと思う) "a?c" "c"、"ac" ""、"a"、"d" 分からん・・・バグってないか?
同上 同上 "a?" ""、"c"、"z"、"zzz" (なし) 何にでもマッチするぞ・・・
\ 後続文字をエスケープ(リテラル化) "a\?" "a?"、"a?b" "c?"、"a!" ?がリテラルとして処理される
  • 上記は、大文字、小文字は区別しない
  • 日本語もOK

5. Where-ObjectってForEach-Objectでもできるんじゃね?

ふと思ったので、試してみたらできた。まあ、好きな方を使えばいいんじゃないかな。

> Get-Childitem | ForEach-Object{ if($_.Name -eq ".android"){$_}}

Mode                 LastWriteTime         Length Name                                                                                        
----                 -------------         ------ ----                                                                                        
d-----        2020/09/21      9:33                .android        

   


バージョン情報

> $PSVersionTable

Name                           Value                                                                                                          
----                           -----                                                                                                          
PSVersion                      5.1.19041.1023