PowerShell – ConvertTo-Json, как получить результат ndjson

Я пытаюсь разделить 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"}
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
0
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если я правильно понимаю, что вы ищете, код можно значительно упростить, используя 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"}

Я понял, что ОП хочет, чтобы выходные данные были в том же формате, что и входные (NDJSON - один полный документ json в строке), просто отфильтрованные с помощью JRNAL_NO в отдельные файлы - что-то вроде $_.group | foreach-object { $_ | convertto-json -compress } | join-string -separator "`n" | set-content ".\JNL\$($_.Name).json", может быть...

mclayton 27.06.2024 23:03

@mclayton полностью, спасибо, добавишь обновление :D впервые слышу о NDJSON

Santiago Squarzon 27.06.2024 23:29

@SantiagoSquarzon - npyw. Кстати, раньше я знал это как «строки json», поэтому имя NDJSON для меня тоже новое :-) - jsonlines.org

mclayton 27.06.2024 23:50

@anhtle рад, что это помогло!

Santiago Squarzon 27.06.2024 23:52

@mclayton Я знал, что он существует, ADX (обозреватель данных Azure) может использовать этот формат для приема, но не знал, что у этого формата есть имя: P

Santiago Squarzon 27.06.2024 23:53

Есть тег jsonlines , который я добавил к вопросу. jsonlines.org (также известный как JSONL), по-видимому, является активно поддерживаемой спецификацией, тогда как http://ndjson.org/ (также известный как NDJSON и ранее LDJSON) сейчас не существует (ссылки на несвязанный сайт на корейском языке). Общим термином для этого формата «по одному объекту JSON за раз» является потоковая передача JSON.

mklement0 28.06.2024 00:35

Всем, кто читает это и имеет оценку 5 или более в теге ndjson и репутацию 25 000 или более: предложите строки jsonlines в качестве синонима на stackoverflow.com/tags/ndjson/synonyms

mklement0 28.06.2024 00:49

Чтобы дополнить полезный ответ от Сантьяго Скварзона предположительно более эффективным решением:
Вы также можете рассмотреть возможность распространения исходных строк («того же формата, что и входной файл») одну за другой, используя пошаговый конвейер, как в этом примере, где вы используете только результат 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() }
    }

Более подробную информацию и информацию см. в разделе Освоение (пошагового) конвейера

Другие вопросы по теме