【问题标题】:combine multiple powershell cmdlet outputs组合多个 powershell cmdlet 输出
【发布时间】:2016-01-10 23:56:25
【问题描述】:

我需要使用 .NET 中的 CmdLets 将多个 Power Shell 脚本的输出组合为管道输出。

例如:

Command-GetA  -combine  Command-GetB | Command-GetD

所以我想通过管道将GetAGetB 的输出发送到GetD。是否有使用 powershell 脚本或 .NET cmdlet 的紧凑方法来执行此操作?除了将输出存储在数组中然后将其传递到管道之类的方法之外?

另一个复杂的例子可能是:

Command-GetA  -combine  ( Command-GetB | Command-GetD ) | Command-GetF

这应该结合GetAGetB|GetD作为管道输入发送到GetF

编辑:

如果我能做这样的事情就好了 - @( GetA ; GetB) -ConvertToASingleList |获取C

所以OutputOfGetAOutputOfGetB 不应在GetC 上单独调用。两者都应该作为组合数组或列表对象传递给GetC

【问题讨论】:

    标签: .net powershell c#-4.0 pipeline cmdlets


    【解决方案1】:

    @PetSerAl 建议的解决方案似乎满足您的要求:

    PS C:\> function Foo { 1..3 }
    PS C:\> function Bar { 2..4 }
    PS C:\> & { Foo; Bar | % { $_ + 2 } } | oh
    1
    2
    3
    4
    5
    6
    

    脚本块将所有输出组合成一个数组。这种行为记录在about_Script_Blocks

    脚本块以单个对象或数组的形式返回脚本块中所有命令的输出。

    【讨论】:

    • 我认为你的解决方案更好,因为它不缓冲任何东西。
    【解决方案2】:

    虽然不是很紧凑,但我会这样做:

        $alldata = @()
    
        $geta = command-geta
        $getb = command-getb
        $getc = command-getc
    
    
        #of course creating a function would be much more nicer in case the structure of A, B and C is the same
    
        foreach ($a in $geta)
            {
            $temp = New-Object System.Object
            $temp | Add-Member -MemberType NoteProperty -Name "aonedata" -Value $a.one
            $temp | Add-Member -MemberType NoteProperty -Name "atwodata" -Value $a.two
            $alldata += $temp   
            }
    
        foreach ($b in $getb)
            {
            $temp = New-Object System.Object
            $temp | Add-Member -MemberType NoteProperty -Name "bonedata" -Value $b.one
            $temp | Add-Member -MemberType NoteProperty -Name "btwodata"    -Value $b.two
            $alldata += $temp   
            }
    
        foreach ($c in $getc)
            {
            $temp = New-Object System.Object
            $temp | Add-Member -MemberType NoteProperty -Name "conedata" -Value $c.one
            $temp | Add-Member -MemberType NoteProperty -Name "ctwodata" -Value $c.two
            $alldata += $temp   
            }
    
        write-host $alldata
        $alldata | convertto-csv | out-file "c:\temp\lotsofdata.txt"
    

    【讨论】:

      【解决方案3】:

      这给了我想要的最终结果:

      $( 命令-GetA; 命令-GetB )|分组结果 |命令-GetC

      因此,如果“GetC”是一个连接 cmdlet,则整个“GetC”cmdlet 代码只对我的所有输入文件运行一次(每次运行“concat”时都会重新创建我的输出文件)

      虽然这里所有的答案都是正确的,但我的要求有点不同:)

      编辑:

      这太完美了!

      ,@(Command-GetA;Command-GetB)|Command-GetC

      感谢@PetSerAl

      【讨论】:

      • 所以,您的实际要求有点不同,输出应该作为单个项目而不是元素传递。但是,如果您想将数组作为单个项目传递,则没有其他可能的方法,然后首先创建该数组并将输出存储在其中(您问题中的短语:除了将输出存储在数组中然后将其传递给管道?,这真的误导了您的意图)。如果我对您的真正要求是正确的,那么这就是您所需要的:,@(Command-GetA;Command-GetB)|Command-GetC
      • 是的,你说得非常正确!我的意思是我不想在一行 cmd 中声明一个单独的数组。然后使用该数组传递给 GetC,它将成为另一行 cmd。我基本上想在一行中完成它。抱歉应该正确地表达我的问题。非常感谢!
      【解决方案4】:

      如果有人遇到上述不适用于的奇怪边缘情况,您也可以使用 -join。

      EG。

      -join($(Command-GetA), "," , $(Command-GetB))
      

      这会产生一个适合 csv 的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多