如何在管道中处理$ null

时间:2010-12-05 00:51:42

标签: powershell

我的PowerShell代码中经常出现以下情况:我有一个返回对象集合的函数或属性,或$null。如果将结果推送到管道中,那么如果$null是唯一的元素,您还可以处理管道中的元素。

示例:

$Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" }

如果没有功能($ Project.Features返回$ null),您将看到一行“功能名称:”。

我认为有三种方法可以解决这个问题:

if ($Project.Features -ne $null)
{
  $Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" }
}

$Project.Features | Where-Object {$_ -ne $null) | Foreach-Object { 
  Write-Host "Feature name: $($_.Name)" 
}

$Project.Features | Foreach-Object { 
  if ($_ -ne $null) {
    Write-Host "Feature name: $($_.Name)" }
  }
}

但实际上我并不喜欢这些方法中的任何一种,但您认为最佳方法是什么?

4 个答案:

答案 0 :(得分:26)

我不认为任何人都喜欢“foreach($ a in $ null){}”和“$ null | foreach-object {}”迭代一次的事实。不幸的是,除了你演示的方式之外别无他法。你可能会更精辟:

$null | ?{$_} | % { ... }

?{$_}where-object {$_ -ne $null}的简写,因为$null被评估为布尔表达式将被视为$false

我在我的个人资料中定义了一个过滤器,如下所示:

filter Skip-Null { $_|?{ $_ } }

用法:

$null | skip-null | foreach { ... }

过滤器与函数相同,但默认块为process {} not end {}。

更新:从PowerShell 3.0开始,$null不再可作为集合进行迭代。耶!

-Oisin

答案 1 :(得分:12)

如果你可以修改你的函数,让它返回一个空的集合/数组而不是$ null:

PS> function Empty { $null }
PS> Empty | %{'hi'}
hi

PS> function Empty { @() }
PS> Empty | %{'hi'}

否则,请考虑Oisin的建议,尽管我会建议稍微调整一下:

filter Skip-Null { $_|?{ $_ -ne $null } } 

否则,这也会过滤0$false

2012年4月30日更新:PowerShell v3中已修复此问题。 V3不会迭代标量$ null值。

答案 2 :(得分:2)

快速记录基思完成它的答案

就个人而言,我会返回 nothing 。这很有道理:

PS> function Empty { if ('a' -eq 'b') { 'equal' } }
PS> Empty | % { write-host result is $_ }

但是,如果您将Empty的结果分配给变量,那么现在您遇到了问题:

PS> $v = Empty
PS> $v | % { write-host result is $_ }

有一个小技巧可以让它发挥作用。只需将Empty的结果包装为如下数组:

PS> $v = @(Empty)
PS> $v | % { write-host result is $_ }
PS> $v.GetType()
IsPublic IsSerial Name      BaseType
-------- -------- ----      --------
True     True     Object[]  System.Array
PS> $v.Length
0

答案 3 :(得分:2)

另一种可能性:

$objects | Foreach-Object -Begin{If($_ -eq $null){continue}} -Process {do your stuff here}

about_Continue

中的更多信息