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

时间:2019-05-29 19:45:35

标签: powershell powershell-v6.0

如果我有这样的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。

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

我已经考虑过以某种方式使用Group-Object,但是我还没有弄清楚如何使它工作。

2 个答案:

答案 0 :(得分:2)

在这里请求代码被认为是题外话。但是,出于自我训练的目的,以下代码段可以完成这项工作。部分注释并逐项列出(辅助)中间变量:

$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

答案 1 :(得分:0)

我认为以下应该可行:

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"