2017-02-13 21 views
0

很简单的场景:的NullReferenceException当阵列在PowerShell中的分组集合

  • 有从文件解析日志的阵列
  • 每个日志具有财产Exceptions就是从日志正文分析异常的阵列
在解析器
$logs | Get-Member 
Name  MemberType Definition 
----  ---------- ---------- 
Equals  Method  bool Equals(System.Object obj) 
GetHashCode Method  int GetHashCode() 
GetType  Method  type GetType() 
ToString Method  string ToString() 
Content  Property string Content {get;set;} 
Exceptions Property string[] Exceptions {get;set;} 
Line  Property int Line {get;set;} 
Source  Property string Source {get;set;} 
Time  Property System.Nullable[datetime] Time {get;set;} 

单元测试证实Exceptions从不为空。 另外:

$logs | where {$_.Exceptions -eq $null} | measure 

Count : 0 
Average : 
Sum  : 
Maximum : 
Minimum : 
Property : 

但是:

$logs | group {$_.Exceptions} 
group : Object reference not set to an instance of an object. 
At line:1 char:6 
+ $l | group {$_.Exceptions} 
+  ~~~~~~~~~~~~~~~~~~~~~ 
+ CategoryInfo   : NotSpecified: (:) [Group-Object], NullReferenceException 
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.PowerShell.Commands.GroupObjectCommand 

所以考虑到检查测量与空例外元素数量返回零这应该工作完全如上呼叫:

$logs | where Exceptions -ne $null | group {$_.Exceptions} 

但这次它成功了:

Values : {SecurityException} 
Count : 28 
Group : {ErrorLog, ErrorLog, ErrorLog, ErrorLog...} 
Name : SecurityException 

Values : {ValidationException} 
Count : 707 
Group : {ErrorLog, ErrorLog, ErrorLog, ErrorLog...} 
Name : ValidationException 

Values : {SoapException ValidationException} 
Count : 6 
Group : {ErrorLog, ErrorLog, ErrorLog, ErrorLog...} 
Name : SoapException ValidationException 

问题是为什么它成功后,我筛选出所有元素为空Exceptions而measure-object暗示那里没有任何空值

解决方案分组我的日志(不够好,因为我不需要组,算了算具体OCCURENCES的):

function Group-Logs([Log[]]$logs) 
{ 
    $logs | where {$_.Exceptions.Count -gt 0} | group {$_.Exceptions} -NoElement | sort Count 

    $noExceptionsLogsNumber = ($logs | where {$_.Exceptions.Count -eq 0}).Count 
    Write-Host "Logs with no exceptions found: $noExceptionsLogsNumber" 
} 

回答

1

注意,例外属性是一个字符串数组。所有比较运算符都可以用作标量(单项)和数组运算符。当用于标量时,它返回一个布尔值($ true/$ false)。对阵列使用时,它返回匹配条件的数组的所有成员。

$logs | where {$_.Exceptions -eq $null} | measure 

返回0项,因为$ _。Exceptions数组中没有空字符串。

+0

这已经是东西了,谢谢:)我实际上运行了这个'$ logs |其中{$ _。Exceptions.Count -eq 0} |测量“,并发现结果恰好是没有例外的日志数量。 所以我相信当我在数组上调用'Group-Object'时,它会比较内部的字符串,并且null在这里不是令人满意的,或者是创建组的关键。有什么方法可以强制'Group-Object'使用空数组而不丢弃它们或添加空字符串? – yoger