about_For

簡単な説明

条件付きテストに基づいてステートメントを実行するために使用できる言語コマンドについて説明します。

詳細な説明

For ステートメント (For ループとも呼ばれます) は、指定した条件が$trueに評価される間にコマンド ブロックでコマンドを実行するループを作成するために使用できる言語コンストラクトです。

For ループの一般的な用途は、値の配列を反復処理し、これらの値のサブセットを操作することです。 ほとんどの場合、配列内のすべての値を反復処理する場合は、 Foreach ステートメントの使用を検討してください。

構文

For ステートメントの構文を次に示します。

for (<Init>; <Condition>; <Repeat>)
{
    <Statement list>
}

Init プレースホルダーは、ループが開始される前に実行される 1 つ以上のコマンドを表します。 通常は、ステートメントの Init 部分を使用して、開始値を使用して変数を作成および初期化します。

この変数は、 For ステートメントの次の部分でテストされる条件の基礎になります。

Condition プレースホルダーは、$trueまたは $false Boolean 値に解決されるFor ステートメントの部分を表します。 For ループが実行されるたびに、PowerShell によって条件が評価されます。 ステートメントが $trueされている場合は、コマンド ブロック内のコマンドが実行され、ステートメントが再び評価されます。 条件がまだ $true場合は、 Statement リスト内のコマンド もう一度実行します。 ループは、条件が $falseになるまで繰り返されます。

Repeat プレースホルダーは、ループが繰り返されるたびに実行される 1 つ以上のコマンドをコンマで区切って表します。 通常、これは、ステートメントの Condition 部分内でテストされる変数を変更するために使用されます。

Statement リスト プレースホルダーは、ループが入力または繰り返されるたびに実行される 1 つ以上のコマンドのセットを表します。 Statement リストの内容は中かっこで囲まれています。

複数の操作のサポート

Init ステートメントの複数の割り当て操作では、次の構文がサポートされています。

# Comma separated assignment expressions enclosed in parentheses.
for (($i = 0), ($j = 0); $i -lt 10; $i++)
{
    "`$i:$i"
    "`$j:$j"
}

# Sub-expression using the semicolon to separate statements.
for ($($i = 0;$j = 0); $i -lt 10; $i++)
{
    "`$i:$i"
    "`$j:$j"
}

Repeat ステートメントの複数の割り当て操作では、次の構文がサポートされています。

# Comma separated assignment expressions.
for (($i = 0), ($j = 0); $i -lt 10; $i++, $j++)
{
    "`$i:$i"
    "`$j:$j"
}

# Comma separated assignment expressions enclosed in parentheses.
for (($i = 0), ($j = 0); $i -lt 10; ($i++), ($j++))
{
    "`$i:$i"
    "`$j:$j"
}

# Sub-expression using the semicolon to separate statements.
for ($($i = 0;$j = 0); $i -lt 10; $($i++;$j++))
{
    "`$i:$i"
    "`$j:$j"
}

Note

事前インクリメントまたは事後インクリメント以外の操作は、すべての構文で機能しない場合があります。

複数の Conditions の場合 次の例に示すように論理演算子を使用します。

for (($i = 0), ($j = 0); $i -lt 10 -and $j -lt 10; $i++,$j++)
{
    "`$i:$i"
    "`$j:$j"
}

詳細については、「 about_Logical_Operators」を参照してください。

構文の例

少なくとも、 For ステートメントでは、 InitCondition、および Repeat ステートメントの一部を囲むかっこと、ステートメントの Statement リスト 中かっこで囲まれたコマンドが必要です。

今後の例では、 For ステートメントの外側に意図的にコードが表示されることに注意してください。 後の例では、コードは For ステートメントに統合されています。

たとえば、次の For ステートメントは、Ctrl キーを押しながら C キーを押してコマンドを手動で中断するまで、 $i 変数の値を継続的に表示します。

$i = 1
for (;;)
{
    Write-Host $i
}

次の例に示すように、 $i の値がループを実行するたびに 1 ずつインクリメントされるように、ステートメント リストにコマンドを追加できます。

for (;;)
{
    $i++; Write-Host $i
}

Ctrl キーを押しながら C キーを押してコマンドを中断するまで、このステートメントでは、ループが実行されるたびに 1 ずつインクリメントされるため、 $i 変数の値が継続的に表示されます。

For ステートメントのステートメント リスト部分の変数の値を変更するのではなく、For ステートメントの Repeat 部分を次のように使用できます。

$i=1
for (;;$i++)
{
    Write-Host $i
}

このステートメントは、Ctrl キーを押しながら C キーを押してコマンドから抜け出すまで、無期限に繰り返されます。

conditionを使用して、For ループを終了できます。 条件は、For ステートメントの Condition 部分を使用して配置できます。 条件が$falseに評価されると、For ループは終了します。

次の例では、$iの値が 10 以下である間、For ループが実行されます。

$i=1
for(;$i -le 10;$i++)
{
    Write-Host $i
}

For ステートメントの外部で変数を作成および初期化する代わりに、For ステートメントの Init 部分を使用して、For ループ内でこのタスクを実行できます。

for($i=1; $i -le 10; $i++){Write-Host $i}

セミコロンの代わりに復帰を使用して、For ステートメントの InitCondition、および Repeat 部分を区切ることができます。 次の例は、この代替構文を使用する For を示しています。

for ($i = 0
  $i -lt 10
  $i++){
  $i
}

この代替形式の For ステートメントは、PowerShell スクリプト ファイルと PowerShell コマンド プロンプトで機能します。 ただし、コマンド プロンプトで対話型コマンドを入力する場合は、セミコロンで For ステートメント構文を使用する方が簡単です。

For ループは、パターンを使用して配列またはコレクション内の値をインクリメントできるため、Foreach ループよりも柔軟性が高くなります。 次の例では、$i変数は、For ステートメントの Repeat 部分で 2 ずつインクリメントされます。

for ($i = 0; $i -le 20; $i += 2)
{
    Write-Host $i
}

For ループは、次の例のように 1 行に記述することもできます。

for ($i = 0; $i -lt 10; $i++) { Write-Host $i }

機能の例

次の例では、 For ループを使用してファイルの配列を反復処理し、名前を変更する方法を示します。 work_items フォルダー内のファイルには、ファイル名として作業項目 ID があります。 ループはファイルを反復処理して、ID 番号が 0 から 5 桁に埋め込まれるようにします。

最初に、コードは作業項目データ ファイルの一覧を取得します。 これらはすべて、名前に <work-item-type>-<work-item-number> 形式を使用する JSON ファイルです。 $fileList変数に保存されたファイル情報オブジェクトを使用すると、名前で並べ替え、項目が種類別にグループ化されている間、ID による項目の順序が予期しないことがわかります。

$fileList = Get-ChildItem -Path ./work_items
$fileList | Sort-Object -Descending -Property Name
bug-219.json
bug-41.json
bug-500.json
bug-697.json
bug-819.json
bug-840.json
feat-176.json
feat-367.json
feat-373.json
feat-434.json
feat-676.json
feat-690.json
feat-880.json
feat-944.json
maint-103.json
maint-367.json
maint-454.json
maint-49.json
maint-562.json
maint-579.json

作業項目を英数字で並べ替えられるようにするには、作業項目番号をゼロで埋め込む必要があります。

コードは、最初に最も長い数値サフィックスを持つ作業項目を検索することによってこれを行います。 for ループを使用してファイルをループ処理し、インデックスを使用して配列内の各ファイルにアクセスします。 各ファイル名を正規表現パターンと比較して、作業項目番号を整数ではなく文字列として抽出します。 次に、作業項目番号の長さを比較して、最も長い番号を検索します。

# Default the longest numeral count to 1, since it can't be smaller.
$longestNumeralCount = 1

# Regular expression to find the numerals in the filename - use a template
# to simplify updating the pattern as needed.
$patternTemplate = '-(?<WorkItemNumber>{{{0},{1}}})\.json'
$pattern         =  $patternTemplate -f $longestNumeralCount

# Iterate, checking the length of the work item number as a string.
for (
    $i = 0                 # Start at zero for first array item.
    $i -lt $fileList.Count # Stop on the last item in the array.
    $i++                   # Increment by one to step through the array.
) {
    if ($fileList[$i].Name -match $pattern) {
        $numeralCount = $Matches.WorkItemNumber.Length
        if ($numeralCount -gt $longestNumeralCount) {
            # Count is higher, check against it for remaining items.
            $longestNumeralCount = $numeralCount
            # Update the pattern to speed up the search, ignoring items
            # with a smaller numeral count using pattern matching.
            $pattern = $patternTemplate -f $longestNumeralCount
        }
    }
}

作業項目の最大数がわかったら、ファイルをループして必要に応じて名前を変更できます。 次のコード スニペットでは、ファイル リストを再度反復処理し、必要に応じて埋め込みます。 別の正規表現パターンを使用して、数値カウントが最大値より小さいファイルのみを処理します。

# Regular expression to find the numerals in the filename, but only if the
# numeral count is smaller than the longest numeral count.
$pattern = $patternTemplate -f 1, ($longestNumeralCount - 1)
for (
    $i = 0                 # Start at zero for first array item.
    $i -lt $fileList.Count # Stop on the last item in the array.
    $i++                   # Increment by one to step through the array.
) {
    # Get the file from the array to process
    $file = $fileList[$i]

    # If the file doesn't need to be renamed, continue to the next file
    if ($file.Name -notmatch $pattern) {
        continue
    }

    # Get the work item number from the regular expression, create the
    # padded string from it, and define the new filename by replacing
    # the original number string with the padded number string.
    $workItemNumber = $Matches.WorkItemNumber
    $paddedNumber   = "{0:d$longestNumeralCount}" -f $workItemNumber
    $paddedName     = $file.Name -replace $workItemNumber, $paddedNumber

    # Rename the file with the padded work item number.
    $file | Rename-Item -NewName $paddedName
}

ファイルの名前が変更されたので、ファイルの一覧をもう一度取得し、古いファイルと新しいファイルの両方を名前で並べ替えることができます。 次のスニペットは、新しい配列に保存し、オブジェクトの初期セットと比較するために、ファイルをもう一度取得します。 次に、ファイルの両方の配列を並べ替え、並べ替えられた配列を新しい変数 $sortedOriginal および $sortedPaddedに保存します。 最後に、 for ループを使用して配列を反復処理し、次のプロパティを持つオブジェクトを出力します。

  • Index は、並べ替えられた配列内の現在のインデックスを表します。
  • Original は、現在のインデックスにある元のファイル名の並べ替えられた配列内の項目です。
  • Padded は、現在のインデックスにある埋め込まれたファイル名の並べ替えられた配列内の項目です。
$paddedList = Get-ChildItem -path ./work_items

# Sort both file lists by name.
$sortedOriginal = $fileList    | Sort-Object -Property Name
$sortedPadded   = $renamedList | Sort-Object -Property Name

# Iterate over the arrays and output an object to simplify comparing how
# the arrays were sorted before and after padding the work item numbers.
for (
  $i = 0
  $i -lt $fileList.Count
  $i++
) {
    [pscustomobject] @{
        Index    = $i
        Original = $sortedOriginal[$i].Name
        Padded   = $sortedPadded[$i].Name
    }
}
Index Original       Padded
----- --------       ------
    0 bug-219.json   bug-00041.json
    1 bug-41.json    bug-00219.json
    2 bug-500.json   bug-00500.json
    3 bug-697.json   bug-00697.json
    4 bug-819.json   bug-00819.json
    5 bug-840.json   bug-00840.json
    6 feat-176.json  feat-00176.json
    7 feat-367.json  feat-00367.json
    8 feat-373.json  feat-00373.json
    9 feat-434.json  feat-00434.json
   10 feat-676.json  feat-00676.json
   11 feat-690.json  feat-00690.json
   12 feat-880.json  feat-00880.json
   13 feat-944.json  feat-00944.json
   14 maint-103.json maint-00049.json
   15 maint-367.json maint-00103.json
   16 maint-454.json maint-00367.json
   17 maint-49.json  maint-00454.json
   18 maint-562.json maint-00562.json
   19 maint-579.json maint-00579.json

出力では、埋め込みの後に並べ替えられた作業項目は想定された順序になります。

関連項目