今回は繰返し処理について学んでいきます。
Powershellの繰返し処理は大きく3つあります。
- for文による繰返し
- foreach文による繰返し
- ForEach-Objectによる繰返し
- while文による繰返し
このうち3については別で紹介するとして、今回は1,2について扱っていきます。
※4については、この入門では扱いませんので、興味のある人は自分で調べてみてください。
1. for文による繰返し
まずは基本のfor文から説明します。
for(初期化式;継続条件式;ステップ式){
# 実行したい処理
}
これらの書き方もやはりCやJavaによく似ています。
ただし、if文と同じく比較演算子がPowershellでは少し独特なため、実際の見た目は少し異なります。
では、実際の実装例を見てみましょう。
for($i=0; $i -lt 10; $i++){
Write-Host $i
}
上記は1~9までの値を順番に表示するスクリプトです。
やはり、継続条件式に書かれた-lt
が他の言語で慣れた人からすると分かりにくく感じますね。
何度も書いて、慣れるようにしましょう。
例題1.
for文を使って、1~10までの合計値を表示しなさい。
例題2.
以下の配列の中身を1行ずつすべて表示しなさい。
$arr = "abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"
1.1. break文とcontinue文
ループステートメントでは、継続している間は基本的には毎回{}
で書かれた内容を実施します。
もしこの処理の流れを変えたい場合は、break文やcontinue文を使用します。
1.1.1. break文
こちらはループを強制的に抜ける場合に利用します。
例えば、配列の中から特定の値を探す処理を見てみましょう。
$arr = "a","b","c","d","e","f","g","h","i","j","k","l","m","n"
$s = Read-Host "英小文字1文字を入力"
for($i=0; $i -lt $arr.Length; $i++){
if($arr[$i] -eq $s){
Write-Host ("Found!! pos=" + $i)
break
}
}
まず外側のfor文は配列の中身を順番に確認するためのものになります。
この中で配列arrのi番目の要素がsと一致するかを調べています。
一致しなければ次のループへ進みますが、一致した場合はその位置を表示します。
そして、見つかったらそれ以降を調べる必要がないため、breakで処理を抜けます。
このようにbreakを使うのは、「これ以上繰返し処理を続ける必要がないとき」になります。
1.1.2. continue文
こちらは特定のループをスキップする場合に使います。
以下の例を見てみましょう。
$sum = 0
for($i=1; $i -le 10; $i++){
if($i % 2 -eq 1){
continue
}
$sum += $i
}
Write-Host $sum
まず、if文を無視して読み進めると、1~10までの合計値を求める処理を行っていることが分かります。
ここで、ifの条件をみると、「変数iが奇数」という条件が書かれています。
continue文は実行した瞬間に次のループへ移るため、この場合は「変数iが奇数の場合はスキップ」という処理となります。
このようにcontinue文を使うのは、「繰返し処理したくない特定のステップを飛ばすため」になります。
上記の例から分かるように、break文もcontinue文も基本的にはif文とともに使われることが多いです。
例題3.
for文を使って、1~100までの合計値を計算しなさい。
ただし、合計値が1000を超えた時点でfor文を中断し、その時点での合計値を出力しなさい。
例題4.
以下の配列の中身を1行ずつすべて表示しなさい。
ただし、"m"が含まれている文字列については表示しないこと
※文字列が特定の文字列を含むかどうかの判定は、$文字列.Contains(検索対象)
で判定できる。
$arr = "abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"
2. foreach文による繰返し
foreach文は配列などのデータの集まり(コレクションといいます)に特化した繰返し処理になります。
foreach($変数 in コレクション){
# 実行したい処理
}
foreach文では、コレクションから値を1つずつ取ってきて、変数に格納します。
変数はそのループ内で使用可能なので、この変数を使って{}内の処理を記述します。
具体例として、例題2をforeachで書いてみます。
$arr = "abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"
foreach($v in $arr){
Write-Host $v
}
配列による繰返し処理の場合、
- for文ではループ変数は配列の添え字
- foreach文ではループ変数は配列の中身
という違いがあるので注意しましょう。
例題5.
例題4をforeach文で解きなさい
例題6.
例題1をforeach文で解きなさい
3. コマンドレットとループステートメントの連携
04.変数でも説明した通り、コマンドレットの結果はオブジェクトとして返却され、モノによっては配列のように扱うことが出来ました。
では、コマンドレットの結果をforeach文と組み合わせて使ってみます。
$gci = Get-ChildItem
foreach($v in $gci){
Write-Host ($v.PSPath + ", " + $v.Name)
}
結果は以下の通りとなりました。
(base) PS D:\powershell\data>
$gci = Get-ChildItem
foreach($v in $gci){
Write-Host ($v.PSPath + ", " + $v.Name)
}
Microsoft.PowerShell.Core\FileSystem::D:\powershell\data\sampleFolder1, sampleFolder1
Microsoft.PowerShell.Core\FileSystem::D:\powershell\data\sampleFolder2, sampleFolder2
Microsoft.PowerShell.Core\FileSystem::D:\powershell\data\sample1.py, sample1.py
Microsoft.PowerShell.Core\FileSystem::D:\powershell\data\sample1.txt, sample1.txt
このようにGet-ChildItemなど、結果が複数個返ってくるような処理の場合、実行結果をforeach文に渡してあげることで、1件ずつ処理することが出来ます。
コマンドレット、if文、for文(foreach文)を組み合わせることで、大抵の処理は書くことが出来るようになります。
是非、覚えていきましょう。
例題7.
以下の変数に含まれるすべての中身のLastWriteTimeを表示しなさい。
$gci_r = Get-ChildItem -Recurse
例題8.
例題7の変数に含まれるすべてのファイルサイズの合計値を求めなさい。
各ファイルのファイルサイズはLength属性で確認できる。
Prev : 06. 条件ステートメント
Next : 08. 文字列、パス文字列の操作