我有一个对象数组。我想搜索数组以确定$ obj.NewName中是否存在特定值。如果值是唯一的,则将值放在$ obj.NewName中。如果确实存在,则递增值并再次搜索,直到该值为唯一。
Function CreateObject ($origionalName)
{
$newName = $null
$obj = $null
$obj = New-Object PSObject
$obj | Add-Member -type NoteProperty -Name OrigionalName -Value $origionalName
$obj | Add-Member -type NoteProperty -Name NewName -Value $newName
Return ($obj)
}
Function Get-NewPatchName ($patch)
{
$patch.OrigionalPatchName.split("-") | Foreach {
## Pipelined string is $_. Check if it starts with "KB".
If ($_.substring(0,2) -like "kb" )
{
## This create the new name based on the substring containing "KB...", and adds the existing file extension.
$tempName = $_
## If there is a version number in the original file name, include that in the new name
If ($patch.OrigionalPatchName -like "*-v*")
{
$intPosition = ($patch.OrigionalPatchName.ToUpper()).IndexOf("-V")
$tempName += ($patch.OrigionalPatchName.substring($intPosition+1,2))
}
## Determine if name is unique
{
## STUCK HERE!!!!!!!!!!
}
}
}
}
$patchList = @()
$nameList = "AMD64-all-windows6.0-kb2900986-x64_63", `
"AMD64-all-windows6.0-kb3124275-x64_57", `
"AMD64-all-windows6.0-kb2900986-x64_63"
Foreach ($name in $nameList){
$patchList += CreateObject $name }
Foreach ($patch in $patchList) {
Get-NewPatchName $patch }
Foreach ($patch in $patchList) {
Write-Host "Origional Patch Name: " $patch.OrigionalName
Write-Host "New Patch Name : " $patch.NewName
}
预期结果:
Origional Patch Name: AMD64-all-windows6.0-kb2900986-x64_63
New Patch Name : kb2900986
Origional Patch Name: AMD64-all-windows6.0-kb3124275-x64_57
New Patch Name : kb3124275
Origional Patch Name: AMD64-all-windows6.0-kb2900986-x64_63
New Patch Name : kb2900986a
我会将$ origionalName处理为它的kb#,例如:
$tempName = "kb2900986"
然后我想看看$ patchName在任何$ patch.newName下的patchList中是否已存在。如果是,那么我会将$ tempName增加到
$tempName = "kb2900986a"
再次运行搜索。一旦$ tempName是唯一的
$patch.newName = $tempName
我已经想出如何处理和增加$ tempName。我只是停留在如何搜索$ patchList以确定$ tempName当前是否存在任何$ patch.newName。
答案 0 :(得分:0)
我正在假设您正在使用更新版本的PS,这将不会在PS2中工作,因为它使用了一些有点粗糙的新版本shell的功能你要解决的任务要容易得多。下面的代码将出现在您使用评论标识的区域。
if($patchlist.newname -contains $tempname){
*do whatever you need to do if the list already contains the name*
} else {
*do whatever you need to do if the list doesn't contain the name*
}
这使用了powershell功能,该功能将自动访问.newname
数组中每个项目的$patchlist
属性,并在调用$patchlist.newname
时将其显示为自己的值数组我相信在PS3中引入了有趣的数组功能。我还要通过传递补丁列表(最好使用不同的名称)来确保你的函数保持原子性,但这并不是必需的。
PS2版本
$templist = foreach($name in $patchlist){
$name.NewName
}
if($templist -contains $tempname){
*do whatever you need to do if the list already contains the name*
} else {
*do whatever you need to do if the list doesn't contain the name*
}
这适用于任何版本的powershell,它没有完全优化(为每次迭代创建$ templist数组)但它可以工作,如果你需要额外的速度,你可以根据需要进行更改
答案 1 :(得分:0)
Mike Garuccio's helpful answer包含解决方案的重要指示。
这是一个惯用的PowerShell v2 +解决方案,它还简化了问题中的代码:
# Convert an array of patch names to custom objects containing
# an .OriginalName property with the input patch name, and a yet-to-be-assigned
# .NewName property.
Function CreateObjects ([string[]] $originalNames)
{
foreach ($name in $originalNames) {
[pscustomobject] @{ OriginalName = $name; NewName = $null }
}
}
# Assign a unique name to the .NewName property of all input objects.
Function Set-NewPatchNames ([pscustomobject[]] $patches)
{
# Initialize an aux. hashtable in which we'll keep track of the unique
# new names assigned so far.
$htNewNames = @{}
foreach ($patch in $patches) {
# Extract the KB number from the original name.
# Note: For brevity, the "-v" version-number extraction mentioned in the
# question is skipped.
$newNameCandidate = $patch.OriginalName -replace '.*-kb(\d+).*', '$1'
# Is the candidate for the new name unique?
if ($htNewNames.Contains($newNameCandidate)) { # Name already used.
# Find a unique variation of the name.
$rootName = $newNameCandidate
# Loop and append 'a', 'b', ... until a unique name is found.
# Note: With more than 26 duplicates, you'll run out of letters,
# at which point seemingly random Unicode chars. will be used.
$suffixCharCode = ([int] [char] 'a') - 1
do {
++$suffixCharCode
$newNameCandidate = $rootName + [char] $suffixCharCode
} while ($htNewNames.Contains($newNameCandidate))
}
# Assign the new name and record it in the hashtable of names used so far.
$patch.NewName = $newNameCandidate
$htNewNames.Add($newNameCandidate, $null)
}
}
# The input list of patch names.
$nameList = "AMD64-all-windows6.0-kb2900986-x64_63",
"AMD64-all-windows6.0-kb3124275-x64_57",
"AMD64-all-windows6.0-kb2900986-x64_63"
# Create a collection of custom objects with the original patch name
# stored in .OriginalName, and a yet-to-be-filled .NewName property.
$patchList = CreateObjects $nameList
# Fill the .NewName properties with unique names.
Set-NewPatchNames $patchList
# Output the resulting objects.
$patchList
在PSv5.1中,这会产生(代码 在PSv2中正常工作,但输出的可读性稍差):
OriginalName NewName
------------ -------
AMD64-all-windows6.0-kb2900986-x64_63 2900986
AMD64-all-windows6.0-kb3124275-x64_57 3124275
AMD64-all-windows6.0-kb2900986-x64_63 2900986a