哪些命令对单个项目进行操作,哪些操作对象数组?
Which commands operate on a single item and which take an array of objects?
我一直在尝试学习 PowerShell,目前正在研究将一个命令的输出通过管道传输到另一个命令的输入中。我发现有些命令可以对管道输入的项目数组进行操作,而其他命令只能对数组中的单个项目进行操作。
例如,Where-Object
可以对项目数组进行操作,返回其中的一个子集,而 New-Item
只能对单个项目进行操作。
我必须以不同的方式处理这两种类型的命令,只能对单个项目进行操作的命令必须包含在 ForEach-Object
块中。
例如,Where-Object
不需要 ForEach-Object
:
Get-Service | where Status -eq "Stopped"
但是 New-Item
会:
@("Red", "Blue", "Green") | foreach {new-item -Name $_ -ItemType directory}
如何确定特定命令是可以作用于一组项目,还是只能作用于单个项目?
据我所知,帮助并没有真正提供线索。例如 Where-Object
的帮助说明输入类型是 System.Management.Automation.PSObject
,这对我来说并不意味着它可以是一个对象数组。
编辑: aljodAv 在他的回答中指出,在第二个示例中实际上不需要 ForEach-Object
。可以写成:
@("Red", "Blue", "Green") | new-item -Name {$_} -ItemType directory
但是,问题仍然存在,因为 $_ 表示通过管道传递的集合对象中的当前项。
我认为这不是哪个可以接受数组哪个不能的问题,这更多的是哪些 cmdlet 接受管道输入,哪些不接受,以及哪些 cmdlet 接受管道输入的问题确实接受它,他们如何使用通过管道输送到其中的对象。在大多数情况下,您需要查看您感兴趣的任何 cmdlet 的帮助,看看它是否接受管道输入。
现在,Where-Object
设计用于处理通过管道传输到其中的一组对象,因此它没有具体说明它确实如此,并假定用户将能够弄清楚这一点. New-Item
实际上确实接受了一个要通过管道传递给它的对象数组,但是接受它的参数是 -Value
参数,因此对于大多数人来说这可能有点用处。上面的示例表明您要指定 -Name
参数,该参数不接受管道值。
所以你的问题的答案是,任何接受管道输入的东西都允许你将正确对象类型的数组通过管道传递给它,它会依次处理每个项目,挑战在于确定是否或如何对象将接受管道信息。
对于您的具体示例,我个人认为 New-Item
应该接受管道字符串以适应目录或空文件的创建,或者允许管道 objects/hashtables 以允许创建更多复杂的东西。
But New-Item does:
@("Red", "Blue", "Green") | foreach {new-item -Name $_ -ItemType directory}
不,New-Item 需要 ForEach-object
是不正确的。
看看如何:
'Red', 'Blue', 'Green'|ni -Name{$_} -ItemType directory -whatif
我一直在尝试学习 PowerShell,目前正在研究将一个命令的输出通过管道传输到另一个命令的输入中。我发现有些命令可以对管道输入的项目数组进行操作,而其他命令只能对数组中的单个项目进行操作。
例如,Where-Object
可以对项目数组进行操作,返回其中的一个子集,而 New-Item
只能对单个项目进行操作。
我必须以不同的方式处理这两种类型的命令,只能对单个项目进行操作的命令必须包含在 ForEach-Object
块中。
例如,Where-Object
不需要 ForEach-Object
:
Get-Service | where Status -eq "Stopped"
但是 New-Item
会:
@("Red", "Blue", "Green") | foreach {new-item -Name $_ -ItemType directory}
如何确定特定命令是可以作用于一组项目,还是只能作用于单个项目?
据我所知,帮助并没有真正提供线索。例如 Where-Object
的帮助说明输入类型是 System.Management.Automation.PSObject
,这对我来说并不意味着它可以是一个对象数组。
编辑: aljodAv 在他的回答中指出,在第二个示例中实际上不需要 ForEach-Object
。可以写成:
@("Red", "Blue", "Green") | new-item -Name {$_} -ItemType directory
但是,问题仍然存在,因为 $_ 表示通过管道传递的集合对象中的当前项。
我认为这不是哪个可以接受数组哪个不能的问题,这更多的是哪些 cmdlet 接受管道输入,哪些不接受,以及哪些 cmdlet 接受管道输入的问题确实接受它,他们如何使用通过管道输送到其中的对象。在大多数情况下,您需要查看您感兴趣的任何 cmdlet 的帮助,看看它是否接受管道输入。
现在,Where-Object
设计用于处理通过管道传输到其中的一组对象,因此它没有具体说明它确实如此,并假定用户将能够弄清楚这一点. New-Item
实际上确实接受了一个要通过管道传递给它的对象数组,但是接受它的参数是 -Value
参数,因此对于大多数人来说这可能有点用处。上面的示例表明您要指定 -Name
参数,该参数不接受管道值。
所以你的问题的答案是,任何接受管道输入的东西都允许你将正确对象类型的数组通过管道传递给它,它会依次处理每个项目,挑战在于确定是否或如何对象将接受管道信息。
对于您的具体示例,我个人认为 New-Item
应该接受管道字符串以适应目录或空文件的创建,或者允许管道 objects/hashtables 以允许创建更多复杂的东西。
But New-Item does:
@("Red", "Blue", "Green") | foreach {new-item -Name $_ -ItemType directory}
不,New-Item 需要 ForEach-object
是不正确的。
看看如何:
'Red', 'Blue', 'Green'|ni -Name{$_} -ItemType directory -whatif