2017-06-14 7 views
2

アップストリームコマンドを再実行せずに、いくつかの条件に応じて2つの異なるパスにパイプラインデータを送信する方法はありますか?いくつかの条件によって、データを異なるパイプラインでフォークする方法はありますか?

PS> Get-SomeInterestingData ` 
    | ?{ <condition> } ` 
    | %{ <positive> } ` 
    | %{ <negative> } 

は、私は、ネストされたパイプライン/表現とすることを行うことができ...表記は、ここにすべて間違っているが、これは私が見てみたいものですか!

PS> Get-SomeInterestingData ` 
    | %{ 
     $_ | ?{ <condition> } | %{ <positive> } -or ` 
     $_ | ?{ -not <condition> } | %{ <positive> } 
    } 

データまたはデータ生成関数に直接アクセスすることはできませんが、パイプラインから受け取っている場合はどうなりますか?スクリプトや関数のparamブロックの一部として、...

param(
    [Parameter(ValueFromPipeline = $true)] 
    $InputObject, 
) 
+0

どのバージョンのPowerShellをターゲットにしていますか? –

+0

最新です。 –

答えて

4

Switchコマンドレットを使用できます。

のPowerShell 4.0以降、あなたが Splitモードで Where()拡張メソッドを使用することができて
Switch(Get-SomeInterestingData){ 
    {<positive>} {Do Stuff} 
    {<negative>} {Do Other Stuff} 
} 
+0

Oooh、私はPowerShellのswitch文について忘れていました。 –

+0

スイッチのパラメータで条件スクリプトブロックを実行することはできません。 –

+0

できます。私はいつもそれをする。 – TheMadTechnician

2

悲しいかなくあなたが望むように言います。

技術的には、これはあなたが何を説明しているのですか。ありきたりではある:あなたが何かファンキーしたい場合

1..10 | %{ 
    if ($_ % 2 -eq 0) { #even pipeline 
     $_ | write-host -ForegroundColor green #add whatever you want to happen on this pipeline instead of write-host 
    } else { #odd pipeline 
     $_ | write-host -ForegroundColor cyan #add whatever you want to happen on this pipeline instead of write-host 
    } 
} 

が、これはあまりにも動作します。多くのシナリオでは、より混乱しがちです。

$PipelineIfTrue = { 
    [CmdletBinding()] 
    param ([Parameter(ValueFromPipeline = $true)][PSObject]$InputObject) 
    process { 
     $InputObject | write-host -ForegroundColor green 
    } 
} 
$PipelineIfFalse = { 
    [CmdletBinding()] 
    param ([Parameter(ValueFromPipeline = $true)][PSObject]$InputObject) 
    process { 
     $InputObject | write-host -ForegroundColor cyan 
    } 
} 

1..10 | %{$_ | &@($PipelineIfFalse, $PipelineIfTrue)[($_ % 2 -eq 0)]} 

つまり、パイプライン入力を受け取る2つのスクリプトブロックを作成します。あなたの条件が真と評価された場合に何をすべきかを定義するもの、偽に対するものです。

これらを配列に貼り付け、その配列のインデックスに条件の結果を使用します。すなわち、false(index = 0)の場合、PipelineIfFalseスクリプトを返します。 trueの場合(index = 1)、PipelineIfTrueを返します。

アンパサンドはこのスクリプトを実行するように指示しており、現在の値をこのスクリプトにパイプすると、この匿名関数のパイプラインの引数になります。


更新

私はサディストだから、私が乗って運ばれます。あなたはこれを行うことができます:

1..10 | Fork-Pipeline {$_ % 2 -eq 0} ` 
    { Write-Host -ForegroundColor green } ` 
    { Write-Host -ForegroundColor cyan } 

またはここ

1..10 | Fork-Pipeline ` 
    -If {$_ % 2 -eq 0} ` 
    -Then { Write-Host -ForegroundColor green } ` 
    -Else { Write-Host -ForegroundColor cyan } 

は、コマンドレットです:

function Fork-Pipeline { 
    [CmdletBinding()] 
    param (
     [Parameter(ValueFromPipeline = $true, Mandatory = $true)] 
     [PSObject]$InputObject 
     , 
     [Parameter(Mandatory = $true, Position=0)] 
     [Alias('If')] 
     [ScriptBlock]$Condition 
     , 
     [Parameter(Mandatory = $true, Position=1)] 
     [Alias('Then')] 
     [ScriptBlock]$PiplineIfTrue 
     , 
     [Parameter(Mandatory = $true, Position=2)] 
     [Alias('Else')] 
     [ScriptBlock]$PiplineIfFalse 
    ) 
    begin { 
     #[string]$template = '[CmdletBinding()]param([Parameter(ValueFromPipeline=$true)]$InputObject)process{{$InputObject | {0}}}' 
     [string]$template = '$_ | {0}' #much simpler version of the above 
     $FunctionIfTrue = [scriptblock]::Create($template -f $PiplineIfTrue.ToString()) 
     $FunctionIfFalse = [scriptblock]::Create($template -f $PiplineIfFalse.ToString()) 
    } 
    process { 
     if (&$Condition) { 
      $InputObject | &$FunctionIfTrue 
     } else { 
      $InputObject | &$FunctionIfFalse 
     } 
    } 
} 

私もそのアプローチはお勧めしません。それは驚くほどうまく実行するつもりはなく、通常のPSパイプラインを扱うのに慣れている人は混乱するでしょう。学術的な楽しみのためだけに良い。

+1

ああ、古い「if文」!私はPowerShellのパイプライニングに慣れているので、それを忘れていました。 –

+1

ええ、それは間違いなく楽しく、おそらくそれを理解する努力の価値はありません:) –

5

入力コレクションを2に分割されます
$Even,$Odd = @(1..10).Where({$_ % 2 -eq 0},'Split') 

、これらのフィルタを満たすアイテム、およびそれらのそのドン't。入力コレクションを再度定義せずに、それぞれを操作できます

+1

これを投稿するためにここに来ました。 '.Where()'メソッドには本当に便利な機能があります。 – briantist

+0

これは私がこのサイトを愛する理由です。今私は新しいものを探しています。 – TheMadTechnician

+1

@TheMadTechnician第3引数も取るオーバーロードがありますが、私はあなた自身で探索することをお勧めします;-) 2番目は '[System.Management.Automation.WhereOperatorSelectionMode]' –

関連する問題