If I have some JSON like this:
$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"
}
]
}
where there is an attachments
array and each element in that array has the same name but different URLs, how can I change all the names so that it outputs like this:
$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"
}
]
}
"@
which renames each attachment to prevent duplicate names, but it preserves the URLs.
Ideally, the code would also make sure none of the new names already exist in the array as well. So if there is already an attachment named (attachment.eml)[1].eml
in the array, it would handle that as well.
I've thought about somehow using Group-Object
but I haven't quite figured out how to make that work.
Requesting for code is considered off-topic here. However, for self-training purposes, the following code snippet could do the job. Partially commented and itemized to (auxiliary) intermediate variables:
$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
Result:
$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