PowerShell - 重命名对象数组中的重复文件名

PowerShell - Rename duplicate filenames in an object array

如果我有这样的JSON:

$inputJson = @"
{
    "attachments" :
        [
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment1.com"
            },
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment2.com"
            },
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment3.com"
            }
        ]
}

其中有一个 attachments 数组并且该数组中的每个元素具有相同的名称但不同的 URL,我如何更改所有名称以便它输出如下:

$outputJson = @"
{
    "attachments" :
        [
            {
                "name":  "(attachment.eml)[1].eml",
                "attachment_url":  "https://www.attachment1.com"
            },
            {
                "name":  "(attachment.eml)[2].eml",
                "attachment_url":  "https://www.attachment2.com"
            },
            {
                "name":  "(attachment.eml)[3].eml",
                "attachment_url":  "https://www.attachment3.com"
            }
        ]
}
"@

重命名每个附件以防止重名,但会保留 URL。

理想情况下,代码还会确保 none 个新名称也已存在于数组中。因此,如果数组中已经存在名为 (attachment.eml)[1].eml 的附件,它也会处理该附件。

我曾考虑过以某种方式使用 Group-Object,但我还没有完全弄清楚如何让它发挥作用。

我认为以下应该有效:

uniques = []
new_attachments = []
attachments.forEach( a=> 
    { var u = uniques.find( u => u.name == a.name);
        if (u == undefined) { 
            uniques.push({name: a.name, count: 1}); 
            u = uniques.find(u => u.name == a.name) 
        }else{ 
            u.count++ 
        } 
        new_attachments.push( "(" + a.name.slice(0,-4) + ")[" + u.count + "].eml" )
} )

您必须更改最后一行:

new_attachments.push( "(" + a.name.slice(0,-4) + ")[" + u.count + "].eml" )

至:

a.name = "(" + a.name.slice(0,-4) + ")[" + u.count + "].eml"

请求代码在此处被视为 off-topic。但是,出于 self-training 目的,以下代码片段可以完成这项工作。部分注释并逐项列出(辅助)中间变量:

$inputJson = @"
{
    "attachments" :
        [
            {
                "name":  "(attachment.eml)[2].eml",
                "attachment_url":  "https://www.attachment222.com"
            },
            {
                "name":  "attachmentOne.eml",
                "attachment_url":  "https://www.attachmentOne.com"
            },
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment1.com"
            },
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment2.com"
            },
            {
                "name":  "attachment.eml",
                "attachment_url":  "https://www.attachment3.com"
            },
            {
                "name":  "attachmnt.eml",
                "attachment_url":  "https://www.attachmnt1.com"
            },
            {
                "name":  "attachmnt.eml",
                "attachment_url":  "https://www.attachmnt2.com"
            }

        ]
}
"@
$objectJson     = $inputJson              | ConvertFrom-Json
$AttachsGrouped = $objectJson.attachments | Group-Object -Property Name
$newAttachments = $AttachsGrouped         | ForEach-Object {
    # debug output
    write-host $_.Count, $_.Group.GetType().Name, $_.name -ForegroundColor Cyan
    if ( $_.Count -gt 1 ) {
        $addCnt = 1
        $(  for ( $i = 0; $i -lt $_.Count; $i++ ) 
            {
                # make sure none of the new names already exist in the array
                While ( "($($_.name))[$($i+$addCnt)].eml" -in 
                    $objectJson.attachments.name ) { $addCnt++ }
                [PSCustomObject]@{
                    'name'           = "($($_.name))[$($i+$addCnt)].eml"
                    'attachment_url' = $_.Group[$i].attachment_url
                }
            }
        )
    } else {
        # retain original definition
        $_.Group[0]
    }
}
$outputJson = [PSCustomObject]@{
                                    # for better output readability
    'attachments' = $newAttachments | Sort-Object -Property Name
}
# result
$outputJson   # | ConvertTo-Json -Depth 2

结果:

$outputJson
attachments                                                                     
-----------                                                                     
{@{name=(attachment.eml)[1].eml; attachment_url=https://www.attachment1.com},...
$outputJson.Attachments
name                    attachment_url               
----                    --------------               
(attachment.eml)[1].eml https://www.attachment1.com  
(attachment.eml)[2].eml https://www.attachment222.com
(attachment.eml)[3].eml https://www.attachment2.com  
(attachment.eml)[4].eml https://www.attachment3.com  
(attachmnt.eml)[1].eml  https://www.attachmnt1.com   
(attachmnt.eml)[2].eml  https://www.attachmnt2.com   
attachmentOne.eml       https://www.attachmentOne.com