POSIX-defined xargs
命令获取从标准输入接收的所有项目,并将它们作为命令行参数传递给它在自己的命令行上接收的命令。例如:grep -rn "String" | xargs rm
。
PowerShell中的等效内容是什么?
以下问题都是这样问的:
但是没有正确答案,因为所有答案都使用ForEach-Object
,它将一次处理一个项目(如xargs -n1
),这样可以获得给定示例的预期结果,或者将中间结果存储在变量中,这会冒犯我的功能命令行 -
答案 0 :(得分:25)
我找到了两种方法。第一个可能是更惯用的PowerShell,第二个更忠实于基于管道的xargs
精神。
举个例子,假设我们想将所有猫咪的照片传递给myapp.exe
。
您可以通过在命令字符串中嵌入管道来执行类似于在sh
中使用$(命令替换)的操作:
&"myapp.exe" @(Get-ChildItem -Recurse -Filter *.jpg | Another-Step)
@(...)
从其中的命令创建一个数组,PowerShell会自动将传递给&
的数组扩展为单独的命令行参数。
但是,这并没有真正回答这个问题,因为它只有在您可以控制要传递给的命令时才会起作用,这可能不是这种情况。
您还可以通过使用子表达式来管理对象,将它们收集到数组,然后将数组传输到最终命令来构造“双管道”。
,@(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