Powershell 管道会为了方便用户和所谓的“一致性”(说来有点好笑)而“展开”集合。一元运算符会阻止 powershell 做这个展开。那些例子不太理想,我换个方式试试。
看看下面两个片段的输出
(4, 5, 6) | ForEach-Object {
Write-Host "Pipeline element now: $_"
}
Pipeline element now: 4
Pipeline element now: 5
Pipeline element now: 6
,(4, 5, 6) | ForEach-Object {
Write-Host "Pipeline element now: $_"
}
Pipeline element now: 4 5 6
后一个把整个集合作为单个对象传递,所以不会被展开。它其实是数组,显示空格而不是逗号,是因为默认输出字段分隔符是空格(保存在 $ofs 中)。可以这样观察
"$(4, 5, 6)"
4 5 6
把数组放进字符串后,powershell 会用默认 OFS 连接它的元素。可以改,只是很少需要。
$ofs = '/~/'
"$(4, 5, 6)"
4/~/5/~/6
我自己经常用这个一元运算符的一种情况,就是拆分值之后,仍然想把所有元素放在一个对象里一起传递。
,(-split 'Tavin enjoys powershell') | ForEach-Object {
[PSCustomObject]@{
Who = $_[0]
Does = $_[1]
Topic = $_[2]
}
}
Who Does Topic
--- ---- -----
Tavin enjoys powershell
从英语翻译·查看原文The Powershell pipeline “unwraps” collections for convenience and, amusingly, for user “consistency”. That unary operator stops powershell from performing that unwrapping. Those examples aren't ideal, so I'll try another approach.
Look at what these two snippets produce
(4, 5, 6) | ForEach-Object {
Write-Host "Pipeline element now: $_"
}
Pipeline element now: 4
Pipeline element now: 5
Pipeline element now: 6
,(4, 5, 6) | ForEach-Object {
Write-Host "Pipeline element now: $_"
}
Pipeline element now: 4 5 6
The latter sends the complete collection through as a single object, so it never gets unwrapped. It's an array, and the spaces you see, rather than commas, come from the space used as the default output field separator (held in $ofs). Here's a way to observe that
"$(4, 5, 6)"
4 5 6
Embedding that array in a string makes powershell join its elements using the default OFS. Changing it is possible, although seldom necessary.
$ofs = '/~/'
"$(4, 5, 6)"
4/~/5/~/6
One fairly frequent use for that unary operator in my own work is splitting values while keeping every element together in a single object.
,(-split 'Tavin enjoys powershell') | ForEach-Object {
[PSCustomObject]@{
Who = $_[0]
Does = $_[1]
Topic = $_[2]
}
}
Who Does Topic
--- ---- -----
Tavin enjoys powershell