Я пытаюсь разделить 1 файл NDJSON на несколько файлов NDJSON. Я могу использовать и разделить файл, но проблема в том, что полученные файлы имеют формат JSON. Можно ли вывести данные в формат NDJSON или мне нужно выполнить какие-то манипуляции со строками?
Мой входной файл test.json:
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38116"}
Мой сценарий PowerShell на данный момент:
$json = (Get-Content C:\Temp\test.json) | ConvertFrom-Json
$jnl_list = $json.JRNAL_NO | select -Unique
ForEach ($jnl in $jnl_list) {
$Array = $json | Where-Object {$_.JRNAL_NO -eq $jnl}
$res = ($Array | ConvertTo-Json)
$res | Out-File -FilePath .\JNL\$($jnl).json
}
Мой текущий результат. Вот файл 38115.json:
[
{
"PERIOD": "2024004",
"JRNAL_NO": "38115"
},
{
"PERIOD": "2024004",
"JRNAL_NO": "38115"
},
{
"PERIOD": "2024004",
"JRNAL_NO": "38115"
},
{
"PERIOD": "2024004",
"JRNAL_NO": "38115"
}
]
Мне нужно, чтобы выходной файл был NDJSON, в основном того же формата, что и входной файл. 38115.json должен быть:
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
38116.json должен быть:
{"PERIOD":"2024004","JRNAL_NO":"38116"}

Если я правильно понимаю, что вы ищете, код можно значительно упростить, используя Group-Object.
Чтобы получить формат NDJSON, вы можете перечислить каждый объект из группы объектов (свойство .Group) и передать его в ConvertTo-Json -Compress, а затем отправить этот вывод в свой файл.
$json = Get-Content C:\Temp\test.json | ConvertFrom-Json
foreach ($group in $json | Group-Object JRNAL_NO) {
$group.Group |
ForEach-Object { $_ | ConvertTo-Json -Compress } |
Set-Content ".\JNL\$($group.Name).json"
}
Приведенный выше код с примером данных создаст 2 файла:
38115.json{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
{"PERIOD":"2024004","JRNAL_NO":"38115"}
38116.json{"PERIOD":"2024004","JRNAL_NO":"38116"}
@mclayton полностью, спасибо, добавишь обновление :D впервые слышу о NDJSON
@SantiagoSquarzon - npyw. Кстати, раньше я знал это как «строки json», поэтому имя NDJSON для меня тоже новое :-) - jsonlines.org
@anhtle рад, что это помогло!
@mclayton Я знал, что он существует, ADX (обозреватель данных Azure) может использовать этот формат для приема, но не знал, что у этого формата есть имя: P
Есть тег jsonlines , который я добавил к вопросу. jsonlines.org (также известный как JSONL), по-видимому, является активно поддерживаемой спецификацией, тогда как http://ndjson.org/ (также известный как NDJSON и ранее LDJSON) сейчас не существует (ссылки на несвязанный сайт на корейском языке). Общим термином для этого формата «по одному объекту JSON за раз» является потоковая передача JSON.
Всем, кто читает это и имеет оценку 5 или более в теге ndjson и репутацию 25 000 или более: предложите строки jsonlines в качестве синонима на stackoverflow.com/tags/ndjson/synonyms
Чтобы дополнить полезный ответ от Сантьяго Скварзона предположительно более эффективным решением:
Вы также можете рассмотреть возможность распространения исходных строк («того же формата, что и входной файл») одну за другой, используя пошаговый конвейер, как в этом примере, где вы используете только результат ConvertTo-Json для определения «JRNAL_NO " ценить:
$Pipeline = @{}
Get-Content .\test.json |
ForEach-Object -Process {
$Jnl = ($_ | ConvertFrom-Json).JRNAL_NO
if (!$Pipeline.Contains($Jnl)) {
$Pipeline[$Jnl] = { Set-Content .\$Jnl.json }.GetSteppablePipeline()
$Pipeline[$Jnl].Begin($True)
}
$Pipeline[$Jnl].Process($_)
} -End {
foreach ($Key in $Pipeline.Keys) { $Pipeline[$Key].End() }
}
Более подробную информацию и информацию см. в разделе Освоение (пошагового) конвейера
Я понял, что ОП хочет, чтобы выходные данные были в том же формате, что и входные (NDJSON - один полный документ json в строке), просто отфильтрованные с помощью
JRNAL_NOв отдельные файлы - что-то вроде$_.group | foreach-object { $_ | convertto-json -compress } | join-string -separator "`n" | set-content ".\JNL\$($_.Name).json", может быть...