みなさんはPowershellでLabel(ラベル)を利用したことがありますか?
Labelを利用することでループ制御が容易になったり、フラグなどが不要になったりと非常にメリットが大きいです。使ったことがない方は是非とも利用をオススメします。
単一のループを制御するには制御構文(break/continue)
通常、Powershellでforeachなどでループを抜けるには、breakやcontinueなどのいわゆうる「制御構文」と呼ばれるものを利用します。
breakはそこでそのコードを終了、continueはループの先頭に戻って処理を継続、という流れになります。
ただし、foreachを入れ子で利用した多重ループの場合には、制御構文だけでは対応が難しい場合があります。そのような場合はよく内部でFlagの変数などで判別して制御したりしますが、テンポラリーな変数が増えてコードが複雑で読みにくくなります。
そのような場合にはLabel(ラベル)を使ってすっきりしたコードを書くことができます。それでは使い方をみていきましょう。
多重ループの制御にはLabel(ラベル)
PowerShell で多重ループの内側から一気に抜ける場合は、こんな感じでラベルを書いて制御します。ラベル名は任意の文字列です。
:ラベル名 foreach{
foreach{
if(条件){
continue ラベル名
}
その後の処理
}
その後の処理1
}
多重ループ制御のサンプル
構文だけだと、あまり便利さが伝わらないと思います。
そこで具体的に多重ループを制御するための使い方の例として、2つのCSVファイルの差分をみてみます。何かを管理している2つの台帳や実データの差分をなどを検出する時などのよく発生するパターンで使えます。
例として以下の2つのCSVを用意します。
CSV01.csv
Color
Green
Blue
Purple
Vermilion
Rose
Sky blue
Indigo
Navy
CSV02.csv
Color
Green
Blue
Purple
Vermilion
Sky blue
Navy
Gray
White
これらのデータの差分を検出するPowerShellスクリプトを用意します。
はじめに2つのCSVを読み込んでます。その後にCSV1->CSV2の方向と逆方向での差分データを抽出するスクリプトの例です。文字列がマッチした後にLabel付きのcontinueを使って一番外側のforeachまで飛ばしてます。
CheckDiffCsv.ps1
<#
[説明]
2つのCSVファイルを読み込み差分を検出します
#>
$Csv01s = Import-Csv "./CSV01.csv"
$Csv02s = Import-Csv "./CSV02.csv"
# Check1: CSV01 -> CSV02へのチェック
:label01 foreach($Csv01 in $Csv01s){
# Write-Host $Csv01.color
foreach($Csv02 in $Csv02s){
if($Csv01.Color -eq $csv02.color){
# Write-Host ("["+$Csv01.color+"]は両ファイルに存在します")
continue label01
}
}
# もしマッチしなかった場合にはこの処理の場所まで来るので
Write-Host ("["+$Csv01.color+"]はCSV02に存在しません")
}
Write-Host "------------------------"
# Check2: CSV02 -> CSV01へのチェック
:label02 foreach($Csv02 in $Csv02s){
foreach($Csv01 in $Csv01s){
if($Csv02.Color -eq $csv01.color){
continue label02
}
}
Write-Host ("["+$Csv02.color+"]はCSV01に存在しません")
}
# End Script...
[Rose]はCSV02に存在しません
[Indigo]はCSV02に存在しません
------------------------
[Gray]はCSV01に存在しません
[White]はCSV01に存在しません
いかがだったでしょうか?Label(ラベル)を利用することで簡単に多重ループを制御することができました。使い方は非常に簡単です。知識として知っているか知らないかで差が出る部分ですので是非習得しましょう。
以上となります
コメント