PowerShell - переименование повторяющихся имен файлов в массиве объектов - PullRequest
0 голосов
/ 29 мая 2019

Если у меня есть немного 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 ]

2 голосов
/ 30 мая 2019

Запрос на код здесь считается не по теме. Тем не менее, для целей самообучения, следующий фрагмент кода может сделать эту работу. Частично прокомментированы и разбиты на (вспомогательные) промежуточные переменные:

$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
0 голосов
/ 29 мая 2019

Я думаю, что должно работать следующее:

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"
...