SEくぼたの事件簿

インフラSEとしての活動を記録していきます

PowershellでのWhere-Objectの使い方(たぶん繰り返し処理)

こんにちは!

前回に続いて今回もPowershellでの繰り返し処理について記載します。

今回は若干繰り返し処理っぽくないのですが、試してみた結果コンソールに繰り返し処理っぽい応答が返ってきたので繰り返し処理!ってくくりにさせてもらいました!(適当笑)

 

今回記載していくのは「Where-Object」というものの利用方法についてです。

前回の以下記事では

kbtblog.hatenablog.com

以下の図の2~6行目に該当する所属が”営業"の人にだけFlagに1という値を追加していました。

f:id:KKubo19:20210311183804p:plain

ただ稀に?10行目の営業にもFlagに値を入れたいってケースがあるかと思います。

そんな時簡単に使えるのがWhere-Objectです!

もちろん以前記載したforでもforeachでも記載できます!

Where-Objectはどちらかというと検索に強いイメージですが(検索の速度は遅いかも笑)、今回は強引に値の入力までやってしまいます!

※速度優先の方はforeach使った方がよいかもです!

kbtblog.hatenablog.com

 

  • 今回やること

上記ファイルの所属が"営業"となっている人のFlag列に1という値をいれる

  • 前提

上記ファイルは「Looptest.csv」という名前でC:\tempに保存

$Datas = Import-Csv -Path "C:\temp\Looptest.csv" -Encoding Default

を実行してファイルを$Datasの中にロードしておきます。

 

  • Where-Objectの利用方法

検索対象のオブジェクト | Where-Object{$_."検索対象のヘッダー" 比較演算子 比較対象}

というように利用します。※Where-ObjectはWhereのみでも可です。

今回のパターンでいくと!!

$Datas | Where-Object{$_."所属" -eq "営業"}

となります。

これを実行するとどうなるかというとこんな感じで営業のみ出力されます!

f:id:KKubo19:20210316182957p:plain

ちょっと見ずらいので出力を以下の感じで整えます。

$Datas | Where-Object{$_."所属" -eq "営業"} | Format-Table

f:id:KKubo19:20210316183247p:plain

こんな感じで条件に合致するものだけピックアップしてくることが可能です。

便利~~~♪

ただ!!僕がこれを初めて見たとき思ったのは「$_.」ってなんやねん!ってこと笑

$_はファイル内の1行分を示しています。

下図の赤枠が1回目の処理の$_と思ってください。

f:id:KKubo19:20210316183646p:plain

$_."所属"は1回目の処理での下図ってことになりますね!

f:id:KKubo19:20210316183817p:plain

それが -eq "営業"と記載したので赤枠内の文字が"営業"とイコールだったら

って意味になります。

比較演算子は色々なものが利用できますし、正規表現も利用可能なものもあります。

※曖昧系もいけたかも!

 

では実際にスクリプト作成します!

今回はWhere-Objectでヒットした行のFlag列に1を入力したいので、

以下のように記載します。

$Datas | where{if($_."所属" -eq "営業"){$_.flag = 1}}

f:id:KKubo19:20210316184316p:plain

ちょっと見ずらいのでインデントをちゃんとつけるとこんな感じ

$Datas | where{
    if($_."所属" -eq "営業"){
        $_.flag = 1
    }
}

これを実行するとこんな感じになります。

f:id:KKubo19:20210316184856p:plain

最後にファイルとして出力したいよって方は以下も追加

$Datas | Export-Csv -Path "C:\temp\Looptest.csv" -Encoding Default -NoTypeInformation

全部合わせるとこ~んな感じ

$Datas = Import-Csv -Path "C:\temp\Looptest.csv" -Encoding Default

$Datas | where{
    if($_."所属" -eq "営業"){
        $_.flag = 1
    }
}
$Datas | Export-Csv -Path "C:\temp\Looptest.csv" -Encoding Default -NoTypeInformation

こんな感じでWhere-Objectを利用した繰り返し処理も記述できます。

色んな方の記事を読んでいると繰り返し処理はforeachの方が早いって記事を見かけます!笑

ぜひ用途に応じて使い分けしてください。

 

  • おまけ

せっかくなんで上記をforeachやforで書いたらどうなるのか記載しておきます。

まずはforeachパターン

以下のように記載します。

$Datas = Import-Csv -Path "C:\temp\Looptest.csv" -Encoding Default

foreach($Data in $Datas){
    if($Data."所属" -eq "営業"){
        $Data.flag = 1
    }
}
$Datas | Export-Csv -Path "C:\temp\Looptest.csv" -Encoding Default -NoTypeInformation

続いてforパターン

$Datas = Import-Csv -Path "C:\temp\Looptest.csv" -Encoding Default

for($i = 0; $i -lt $Datas.Count; $i++){
    if($Datas[$i]."所属" -eq "営業"){
        $Datas[$i].flag = 1    
    }
}
$Datas | Export-Csv -Path "C:\temp\Looptest.csv" -Encoding Default -NoTypeInformation

とまあこんな感じでしょうか!

皆さんのレベルだと当たり前かもですが!終了条件で$Data.Countより$iが小さい場合としています。以下じゃだめだよ!配列は0から始まるから配列内の個数を終了条件の数字として比較すると1多くなっちゃうからね!笑

 

次回はPowerhsellから離れてMicrosoft365周りを書いていきたいと思います。

  • 最後に!

Twitterでも情報発信したいと思いますので、興味があったらフォローしてください!