什么相当于PowerShell中的xargs?

时间:2016-04-05 14:15:06

标签: powershell xargs

POSIX-defined xargs命令获取从标准输入接收的所有项目,并将它们作为命令行参数传递给它在自己的命令行上接收的命令。例如:grep -rn "String" | xargs rm

PowerShell中的等效内容是什么?

以下问题都是这样问的:

但是没有正确答案,因为所有答案都使用ForEach-Object,它将一次处理一个项目(如xargs -n1),这样可以获得给定示例的预期结果,或者将中间结果存储在变量中,这会冒犯我的功能命令行 -

2 个答案:

答案 0 :(得分:25)

我找到了两种方法。第一个可能是更惯用的PowerShell,第二个更忠实于基于管道的xargs精神。

举个例子,假设我们想将所有猫咪的照片传递给myapp.exe

方法#1:命令替换

您可以通过在命令字符串中嵌入管道来执行类似于在sh中使用$(命令替换)的操作:

&"myapp.exe" @(Get-ChildItem -Recurse -Filter *.jpg | Another-Step)

@(...)从其中的命令创建一个数组,PowerShell会自动将传递给&的数组扩展为单独的命令行参数。

但是,这并没有真正回答这个问题,因为它只有在您可以控制要传递给的命令时才会起作用,这可能不是这种情况。

方法#2:真正的管道

您还可以通过使用子表达式来管理对象,将它们收集到数组,然后将数组传输到最终命令来构造“双管道”。

,@(Get-ChildItem -Recurse -Filter *.jpg | Another-Step) | %{&"myapp.exe" $_}

像以前一样@(...)将项目收集到一个数组中,然后将数组传送到最终命令,该命令使用%ForEach-Object)调用。通常,这会分别循环遍历每个项目,因为PowerShell会在管道传输时自动展平阵列,但可以通过添加,运算符来避免这种情况。然后正常使用$_特殊变量来嵌入传递的数组。

所以关键是要在,@(...)中包装要收集的管道,然后将其传递给%{...}中的某些内容。

答案 1 :(得分:3)

我一直在将此过滤器用于基本的 xargs 执行。

filter xargs { ($h,$t) = $args; & $h ($t + $_) }

大致相当于:

filter xargs { & $args[0] ($args[1..$args.length] + $_) }

示例

 docker ps -q | xargs docker stop

 gem list | % { $_.split()[0] } | xargs gem uninstall -aIx