Если у меня есть немного 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 ответа
Запрос кода считается не по теме здесь. Однако в целях самообучения эту работу может выполнить следующий фрагмент кода. Частично прокомментированы и разбиты на (вспомогательные) промежуточные переменные:
$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
Я думаю, что должно работать следующее:
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"
Новые вопросы
powershell
PowerShell - это кроссплатформенная утилита командной строки и сценариев от Microsoft. Используйте этот тег только для вопросов о написании и выполнении сценариев PowerShell. Вопросы программирования, относящиеся к кроссплатформенной версии PowerShell Core (Windows, macOS и Linux), должны быть помечены [powershell-core]. Вопросы о системном администрировании следует задавать в случае сбоя суперпользователя или сервера.