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
我正在尝试从 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