【问题标题】:Searching Hash Table Values for Missing Values在哈希表值中搜索缺失值
【发布时间】:2017-08-30 17:12:39
【问题描述】:

我正在尝试搜索包含作为键的主机名和作为值的应用程序的哈希表。我正在寻找不包含特定值 AKA 应用程序的主机名(键)。但是,我的代码似乎无法正常工作,因为我总是收到所有的密钥/主机名。

foreach ($global:computer in $global:hash.keys){  
  if ($global:hash.$global:computer.values -notcontains 'SnagIt'){
    $global:computer
}

}

示例数据:

键、值

Host1:FireFox,Chrome,IE

Host2:Snagit、FireFox、Chrome、IE

Host3:Chrome,IE

$global:hash.$global:computer: 的示例值输出:

{Snagit、FireFox、Chrome、IE...}

哈希表构建代码:

$global:Csv = Import-Csv -LiteralPath $global:ConvertedSNWReport

[HashTable]$global:Hash=@{}

For ($i = 0; $i -lt ($global:Csv."Computer name").Count; $i++)
{
If ($global:Hash.ContainsKey($global:Csv[$i].'Computer name'))
{
    $global:Hash.($global:Csv[$i].'Computer name').Application += $global:Csv[$i].Application
    Continue
}
$global:Hash.($global:Csv[$i].'Computer name') = @{
  Application = @($global:Csv[$i].Application)
}
}

【问题讨论】:

  • 删除.values
  • 这似乎对我不起作用。
  • 我不认为你的哈希表看起来像你想象的那样。索引运算符 ([]) 属于列表变量之后,而不是属性之后,例如$global:Csv[$i].'Computer name'.
  • 我更改了它,但据我所知,它似乎没有任何区别。
  • 啊,我明白了。您需要使用 $Hash.Computer.Application 来获取该 PC 的程序数组。

标签: powershell hashtable


【解决方案1】:

您的哈希表创建将应用程序列表构建为嵌套哈希表:

{
    "Host1": {
        "Application": [ "FireFox", "Chrome", "IE" ]
    },
    "Host2": {
        "Application": [ "Snagit", "FireFox", "Chrome", "IE" ]
    },
    "Host3": {
        "Application": [ "Chrome", "IE" ]
    }
}

像这样导入您的数据:

$hash = @{}
Import-Csv -LiteralPath $global:ConvertedSNWReport | ForEach-Object {
    $hash[$_.'Computer name'] += @($_.Application)
}

获取主机名和应用程序列表之间的直接映射:

{
    "Host1": [ "FireFox", "Chrome", "IE" ],
    "Host2": [ "Snagit", "FireFox", "Chrome", "IE" ],
    "Host3": [ "Chrome", "IE" ]
}

你可以像这样过滤哈希表:

$hash.GetEnumerator() | Where-Object {
    $_.Value -notcontains 'Snagit'
}

如果您想坚持您的数据导入过程(我不推荐),您需要扩展哈希表值的 Application 键:

$hash.GetEnumerator() | Where-Object {
    $_.Value.Application -notcontains 'Snagit'
}

附带说明:尽可能避免使用全局变量。它们通常是在脚本中引入意外状态的辅助通道。特别是不要使用全局变量作为循环变量。在大多数情况下,最好使用局部变量并通过脚本/函数参数从调用者传递数据。

【讨论】:

  • “不起作用”是一个不充分的问题描述。请使用您的哈希表的实际定义方式更新您的问题,就像 Mathias 已经要求的那样。
  • 很抱歉造成混乱,请参阅更新后的帖子。
  • 非常感谢。
  • 如果你能展示你如何做 -notlike 或 -notmatch 'Snagit'
【解决方案2】:

表达式$hashtable.$key 已经解析为键为$key 的条目的值

$global:hash.$global:computer.values 中删除.values 引用

如果值只是带有逗号分隔项的单个字符串,-notcontains 将不起作用,请改用-notlike 运算符:

if($hash.$computer -notlike '*SnagIt*'){...}

【讨论】:

  • @MrMr 更新了答案。您能否用您最初构建哈希表的方式来更新您的答案?
  • 您提供的第二个选项也不起作用。我使用 import-csv 来构建哈希表。
  • @MrMr Import-Csv 生成对象列表,而不是哈希表。请使用您的实际输入数据样本以及您如何阅读它们来更新您的问题。基本上,在您的问题中输入minimal reproducible example
  • 抱歉,我使用了 import-csv,然后用该数据构建了一个哈希表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 2010-10-30
  • 1970-01-01
  • 2017-02-15
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多