PowerShell 中的 xargs 等价物是啥?
Posted
技术标签:
【中文标题】PowerShell 中的 xargs 等价物是啥?【英文标题】:What's the equivalent of xargs in PowerShell?PowerShell 中的 xargs 等价物是什么? 【发布时间】:2016-07-25 13:07:28 【问题描述】:POSIX-defined xargs
命令获取它从标准输入接收的所有项目,并将它们作为命令行参数传递给它在自己的命令行上接收的命令。例如:grep -rn "String" | xargs rm
.
PowerShell 中的等价物是什么?
以下问题都是这样问的:
Convert xargs Bash command to PowerShell? What is the PowerShell equivalent to this Bash command?但没有正确答案,因为所有答案要么使用ForEach-Object
,它将一次处理一个项目(如xargs -n1
),以获得给定示例所需的结果,或者存储中间导致一个变量,这冒犯了我的功能性命令行功能。
【问题讨论】:
嗯,xargs -n1
也很有用。就像 find ... | while read f ; do ... done
... 并且以某种方式通过直觉在 PS 中做到这一点几乎是不可能的。
【参考方案1】:
我找到了两种方法。第一个可能是更惯用的 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 会在管道传输时自动展平数组,但这可以通过预先添加 ,
运算符来避免。然后,$_
特殊变量照常用于嵌入传递的数组。
因此,关键是将要收集的管道包装在,@(...)
中,然后将其通过管道传输到%...
中。
【讨论】:
您也可以使用Foreach($x in (expression))
,它与 xargs 不太一样,但对嵌套对象很有帮助。
哇。这很糟糕。这应该是 powershell 中的本机运算符。在 %&"foo" 的某个地方,我只想放弃。
another-step
是做什么的?
@RenéNyffenegger 这只是作为某个步骤的示例,该步骤输出的内容可用作命令行参数。
我还有一个问题:您编写PowerShell 自动将传递给&
的数组扩展为单独的命令行参数。据我在 PowerShell 7 上看到的,这是执行可执行文件的行为,无论它们是使用 &
还是不使用("myapp.exe" @(Get-ChildItem -Recurse -Filter *.jpg | Another-Step)
也有效。【参考方案2】:
我一直在使用这个过滤器来执行基本的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
【讨论】:
我喜欢语法糖,但不要像xargs -n1
和链接的示例那样一次过滤一个处理项?例如。 ls | echo “hello”
将“hello”附加到输出的每一行。
@simonwo 你是对的,ls | xargs -n1 echo "hello"
将在每个项目之前打印hello
,但ls | xargs echo "hello"
在所有文本输出之前只打印一次 hello。在 powershell 中,使用上述方法,ls | xargs Write-Host "hello "
将在每个项目之前打印hello
,例如 bash -n1
选项。要复制正常的xargs
行为,您可以先将对象强制放入数组,(ls) | xargs Write-Host "hello "
。我所有的用例都属于-n1
模式。这可以更改为一个函数并扩展为接受更多参数并表现得像普通的 xargs。以上是关于PowerShell 中的 xargs 等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Flow 中星号 (*) 类型的用途是啥,TypeScript 中的等价物是啥?
Dart/Flutter 中的 TimingLogger 等价物是啥?