PowerShell Sort-Objectで処理を一度ためる流れの検証1/2

全2話で PowerShell で、複数のデータ(オブジェクト)を複数のコマンドレットで処理する際の、処理の流れについてプログラム実行して検証します。
データ全体に対して並び替えの処理を行う Sort-Object による処理の流れの違いについても検証します。

※ Windows PowerShell 5.1.19041.5965 を使用します。
※プログラムは自己責任でご利用ください。

Sort-Object を入れる前の処理の流れ

以下は、3つのオブジェクト 1, 3, 2 を “Input: 数値” の形式で出力した後、 “Output: 数値” の形式でアプリに表示する PowerShell のプログラムです。

1, 3, 2 |
    ForEach-Object { Write-Host "Input: $_"; $_ } |
    ForEach-Object { Write-Host "Output: $_" }

これを実行する前に、このプログラムで使用するコマンドレットと、2行目の後半の ; $_ について説明します。

ForEach-Object は受け取ったオブジェクトを順次処理する

ForEach-Object コマンドレットでは、パイプラインの上流から1個ずつ渡されてくるオブジェクト逐次処理します。
※パイプラインの上流から渡されたオブジェクトを1個ずつ処理するだけで、この ForEach-Object のスコープでループ処理を行うわけではありません

ForEach-Object コマンドレットは、入力オブジェクトのコレクション内の各項目に対して操作を実行します。 入力オブジェクトは、コマンドレットにパイプ処理することも、 InputObject パラメーターを使用して指定することもできます。

ForEach-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn

ForEach-Object コマンドレットについては、以下の記事も参照してください。

Write-Host コマンドレットで、オブジェクトを表示

Write-Host コマンドレットは、ホスト(例では Windows PowerShell アプリ)に、オブジェクトの内容を表示します。

カスタマイズされた出力をホストに書き込みます。

Write-Host "Red on white text." -ForegroundColor red -BackgroundColor white

このコマンドは、”白いテキストに赤” という文字列を表示します。ForegroundColor パラメーターで定義されているように、テキストは赤です。 BackgroundColor パラメーターで定義されているように、背景は白です。

Write-Host (Microsoft.PowerShell.Utility) – PowerShell | Microsoft Learn

最後に実行した文(式)がパイプで渡すオブジェクトに設定される

2行目は、 Write-Host コマンドレットで “Input: $_” を出力した後に ; 6 と書かれています。

; は、プログラムの文 (Write-Host “Input: $_” など)の区切り文字で、次の新たな文を記述する際に用います。

6 は、”文字列” や 1 + 2 と同じですが、 PowerShell のパイプラインでは、式は文としても扱います。

ところで上記①や②は右辺が式です。代入文の右辺は文じゃなかったの?と思われると思いますが、パイプラインの節で述べた通り、単独の式もパイプラインであり、パイプラインは文なので、三段論法でいくと式は文として扱われることになります。

PowerShellにおける「文」と「式」についての考察 – PowerShell Scripting Weblog

この 6 という式のは、パイプを経た次の処理に渡されるオブジェクトとして $_ 自動変数に格納されます。
その結果、パイプを経た次の処理で “Output: $_” を表示した結果は 1, 3, 2 ではなく、全て 6 になりました。

PS G:\Dev\PowerShell> 1, 3, 2 |
>>     ForEach-Object { Write-Host "Input: $_"; 6 } |
>>     ForEach-Object { Write-Host "Output: $_" }
Input: 1
Output: 6
Input: 3
Output: 6
Input: 2
Output: 6

パイプに渡すオブジェクトがないと処理が終了する

この ; 6 を消した、以下のプログラムを実行するとどうなるでしょう。

1, 3, 2 |
    ForEach-Object { Write-Host "Input: $_"} |
    ForEach-Object { Write-Host "Output: $_" }

Write-Host コマンドレットは出力を返さないため、パイプを経た次の処理にオブジェクト渡されなくなり、次の処理 (例では “Output: $_” の表示) も行われなくなりました。

PS G:\Dev\PowerShell> 1, 3, 2 |
>>     ForEach-Object { Write-Host "Input: $_"} |
>>     ForEach-Object { Write-Host "Output: $_" }
Input: 1
Input: 3
Input: 2

このコマンドレットは出力を返しません。 ホストにオブジェクトを送信します。 ホストは、このコマンドレットが送信するオブジェクトを表示します。

Write-Host (Microsoft.PowerShell.Utility) – PowerShell | Microsoft Learn

オブジェクトが渡されない “Output: $_” を表示する部分の $_ を取り除いても出力はされなかったので、パイプにオブジェクトが渡されなくなった時点で処理が終了すると推測できます。

PS G:\Dev\PowerShell> 1, 3, 2 |
>>     ForEach-Object { Write-Host "Input: $_"} |
>>     ForEach-Object { Write-Host "Output: ?" }
Input: 1
Input: 3
Input: 2

実行結果

冒頭で紹介したプログラムを Windows PowerShell アプリを起動して、プログラムのコピー貼り付けEnter キーで実行します。
※ Windows 10 の場合、エクスプローラアドレスバーpowershell⏎ と入力すると、そのフォルダをカレントディレクトリにして Windows PowerShell アプリを起動できます。

powershell Sort-Object でいったん上流の全ての要素が処理されていったんためられます。3

結果は、一番上流にある 1, 3, 2 という3つの数値のオブジェクト1つずつ順番に処理されました。

1番目のオブジェクト (数値 1) の処理が完了した後に、2番目のオブジェクト (数値 3) の処理が行われ、最後に3番目のオブジェクト (数値 2) の処理が行われました。

PS G:\Dev\PowerShell> 1, 3, 2 |
>>     ForEach-Object { Write-Host "Input: $_"; $_ } |
>>     ForEach-Object { Write-Host "Output: $_" }
Input: 1
Output: 1
Input: 3
Output: 3
Input: 2
Output: 2

今回はここまで

今回は、パイプでつながった処理は、オブジェクト1つずつ順番に実行されることがわかりました。
後半では、このプログラムの中間の処理に Sort-Object コマンドレットを入れた場合の、処理の流れの変化について紹介します。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました