Powershell - 使用通配符从 2 个数组中删除重复项

Powershell - remove duplicates from 2 arrays using wildcards

我正在尝试从 2 个查询的输出中删除重复项并仅保留唯一条目。

我正在使用以下内容提取已安装 Windows 更新的列表(同时去除 12 个空格字符并降为小写:

$A = @(Get-HotFix | select-object @{Expression={$_.HotFixID.ToLower()}} | ft -hidetableheaders | Out-String) -replace '\s{12}',''

然后我查询文件夹中的可用文件列表并使用以下方法去除 3 个尾随空白字符:

$B = @(Get-ChildItem D:\y | select-object 'Name' | ft -hidetableheaders | Out-String) -replace '\s{3}',''

我遇到的问题是第一个查询 ($A) returns 输出如下:

kb4040981
kb4041693
kb2345678
kb8765432

而第二个查询 ($B) returns 输出如下:

windows8.1-kb4040981-x64_d1eb05bc8c55c7632779086079c7759f40d7386f.cab
windows8.1-kb4041687-x64_3bdf264bcfc0dda01c2eaf2135e322d2d6ce6c64.cab
windows8.1-kb4041693-x64_359b7ac71a48e5af003d67e3e4b80120a2f5b570.cab
windows8.1-kb4049179-x64_e6ec21d5d16fa6d8ff890c0c6042c2ba38a1f7c4.cab

我需要在 $A 数组中的每个条目周围使用通配符来比较 2 个输出(我认为),并且它存在于 $B 中的位置从 $B 数组中删除整行。

我无法截断 $B 的输出,因为我需要在后续过程中使用完整的文件名。

IE 在上面的示例输出中,整个第一行和第三行将从 $B 数组中删除,其他行保持不变。

网上搜索了很多方法,用了foreach循环,都无济于事。

提前感谢您的帮助。

我建议您花一点时间学习 Powershell 的基础知识。当您使用格式化 cmdlet 和文本文件而不是对象时,您就失去了好东西。 ;-) 以下是我将如何开始任务:

$A = Get-HotFix
$B = Get-ChildItem D:\y | Select-Object -Property Name,@{Name='HotFixID';Expression={($_.BaseName -split '-')[1]}}
Compare-Object -ReferenceObject $A -DifferenceObject $B -Property 'HotFixID' -PassThru

您尝试过哪些 foreach 循环不起作用?除非您的输出很大,否则这种方法非常简单。

$a = "kb4040981","kb4041693","kb2345678","kb8765432","test"
[System.Collections.ArrayList]$b = "windows8.1-kb4040981-x64_d1eb05bc8c55c7632779086079c7759f40d7386f.cab","windows8.1-kb4041687-x64_3bdf264bcfc0dda01c2eaf2135e322d2d6ce6c64.cab","windows8.1-kb4041693-x64_359b7ac71a48e5af003d67e3e4b80120a2f5b570.cab","windows8.1-kb4049179-x64_e6ec21d5d16fa6d8ff890c0c6042c2ba38a1f7c4.cab"

$toRemove = New-Object System.Collections.ArrayList

foreach($kb in $a)
{
    foreach($line in $b)
    {
        if($line -match $kb)
        {
            write-host "$kb found in: $line" -ForegroundColor Green
            $toRemove.add($line) | out-null
        }
    }
}

foreach($line in $toRemove)
{
    $b.Remove($line)
}

$b

希望对您有所帮助。

衷心感谢sambardo的耐心和投入!基于他的优秀推荐的最终工作解决方案是:

$a = (Get-Hotfix).hotfixID
$b = (Get-ChildItem D:\y\ -file *.cab).name
$toRemove = New-Object System.Collections.ArrayList
  foreach($kb in $a)
{
    foreach($line in $b)
  {
      if($line -match $kb)
    {
#            write-host "$kb found in: $line" -ForegroundColor Green
            $toRemove.add($line) | out-null
      }
    }
}
foreach($line in $toRemove)
{
  $b.Remove($line)
}
$b