2007/06/10
ネストされたスクリプトブロック内での$_
たとえば、2階層下のフォルダまで(無限階層じゃないのがミソ)のファイル・フォルダのフルパスを取得するスクリプトを考えます。
dir|%{$_.Fullname;if ($_.PSIsContainer){dir $_|%{$_.Fullname}}}
こんな感じでしょうか。
実行例。-recurseパラメータをつけた場合は3階層目までさらいますが、上記のスクリプトは二階層目で止まります。
PS C:\s> dir -recurse |%{$_.fullname}
C:\s\t
C:\s\新規 「サクラ」用音楽テキスト.mml
C:\s\t\u
C:\s\t\新規 Microsoft Office PowerPoint プレゼンテーション.pptx
C:\s\t\u\v
C:\s\t\u\v\新しいビットマップ イメージ.bmp
PS C:\s> dir|%{$_.Fullname;if ($_.PSIsContainer){dir $_|%{$_.Fullname}}}
C:\s\t
C:\s\t\u
C:\s\t\新規 Microsoft Office PowerPoint プレゼンテーション.pptx
C:\s\新規 「サクラ」用音楽テキスト.mml
PS C:\s>
さて、このForEach-Objectコマンドレット(エイリアスは%)はネストされています。最初の$_.Fullnameは最初のdir(Get-ChildItemコマンドレット)が返すFileInfo/DirectoryInfoオブジェクトのFullnameプロパティを見ています。その次の$_.PSIsContainerもそうですね。$_がフォルダだったら次のdirを実行します。dir $_の$_も最初のオブジェクトです。さてここでふたたびForEachループを回します。ここで実行される$_.Fullnameの$_は、直前のdir $_が返したFileInfo/DirectoryInfoオブジェクトを参照しています。
このようにスクリプトブロックをネスト化した場合、$_にはもっとも内側のパイプラインを通ったオブジェクトが格納されます。
さて、では内側のスクリプトブロックから、外側のスクリプトブロックのパイプラインにわたったオブジェクトを参照するにはどうするのでしょう?この場合、たとえば最初から見て1階層下のフォルダC:\s\tのdirを内側のスクリプトブロックで回す際、外側のC:\s\tのフルパスも合わせて表示したいとき、内側から外側の$_を参照する必要がでてきます。このやり方は実は分かりません(汗 できるのかな~?
一晩寝たら思いつきました。コロンブスの卵です。外側の$_をほかの変数に入れちゃえばOKですね。
PS C:\s> dir|%{$_.Fullname;if ($_.PSIsContainer){$outer=$_;dir $_|%{"[" + $outer .Fullname + "]";$_.Fullname;}}}元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/06/10/80193.aspx
プライバシーポリシー