搜索大型 Powershell 阵列

Searching through large Powershell arrays

警告:Powershell新手,terms/code可能不正确

假设我有一个 Powershell 数组,其中包含来自 Invoke-Sqlcmd 的数据,比如 10,000“行”,每行有六列 (Col1-Col6)。假设我想找到 Col5 为空的每一行。现在我在做

foreach ($row in $sqlimport.col1)
 { $col5data = $sqlimport.Where({$_.col1 -eq $row}) | Select-Object -ExpandProperty Col5
if ( '' -eq $col5data ) {$col5data+1} else {} $col5data

Returns 1,在我的测试中应该是这样。代码似乎错误且缓慢。 运行 需要几分钟时间。当

$sqlimport.Where({$_.col5 -eq 'somedatathatisthere'})

需要几毫秒

然而,

$sqlimport.Where({$_.col5 -eq ''})

Returns空白

($sqlimport.Where({$_.col5 -eq ''})).Count

Returns 0

现在,您要求 PowerShell 创建一个由列 col1 中的所有值组成的数组,然后在每次迭代中再次搜索 整个数组 找到对应的 col5 值。那完全没有必要。

简单地遍历数组本身:

foreach($row in $sqlimport){
    if($row.Col5 -like ''){
        Write-Host "Col5 is empty in row with id $($row.Col1)"
    }
}

这只会遍历整个数组一次

explains the problem with the inefficiency of your first attempt well and offers a solution that ultimately performs best, due to use of a (single) foreach statement (as opposed to the much slower ForEach-Object cmdlet).

但是,使用(单一).Where() array method call (or the related .ForEach() 方法的解决方案:

  • 稍微[1]
  • 同时更简洁,并且可以说在概念上更优雅。

这是您在 $sqlimport.Where({ $_.col5 -eq '' }) 上尝试过的方法,根据您的反馈,只需要一个小的调整就可以实现:

  • 而不是-eq '' 使用-like '',这是一个有点晦涩的[2] 测试空字符串(''以及 $null(也用于 Mathias 的回答) - 它本质上是 .NET 的 [string]::IsNullOrEmpty() 方法 .
  • 等价物
# -like matches both '' and $null
$sqlimport.Where({ $_.col5 -like '' })

注:

  • 如果您希望测试$null,请使用以下内容;请注意 $null 是如何放置在 LHS 上的,这对于稳健比较通常是可取的[3]:

    $sqlimport.Where({ $null -eq $_.col5 })
    
    • 顺便说一句:GitHub issue #10656 提议为 $null 引入一个简化的测试,例如 -is $null;不幸的是,相关的 PR 已被放弃。
  • 顺便说一句:[string]-type-constrained PowerShell 变量 从不存储 $null 值:
    [string] $str = $null 导致 $str 包含 '',而不是 $null。但是,[string] 类型的 属性 值 未在 PowerShell 代码中填充 可以 包含 $null 值,因为在你的情况下。

    • 为了在 PowerShell 代码中将真实的 $null 值传递给 string 类型的 .NET API,[=77=必须使用 ]special singleton(直接传递 $null 将再次导致 ''): [NullString]::Value`
    • 有关背景信息,请参阅

[1] 有关 PowerShell 的各种枚举(迭代)功能的 性能比较 ,请参阅 this answer.[=123 的底部部分=]

[2] -like operator is to perform wildcard表达式匹配的真正目的。快捷方式依赖于
-like - 它仅对 (non-null) strings 进行操作 - auto-converting non-string 操作数字符串,在 $null 的情况下会导致转换为 '' 空字符串 )。

[3] 要可靠地测试 $null,请将其放在 -eq / [=44= 的 LHS 上] 手术;例如,$null -eq $var。如果你将 $null 放在 RHS - $var -eq $null - 而 $var 恰好是一个 集合 (例如数组), return值为匹配元素数组,即$var元素的数组值为$null ,这是一个不同的操作 - 请参阅 about_Comparison_Operators