Конвертировать в csv из json в PowerShell
это мой csv:
"name,data
Play,http://{gho}.domain.com/
BDomain,domain.com
Charts,2
Compress,0
CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json
Дает мне:
[
{
"name": "Play",
"data": "http://{gho}.domain.com/"
},
{
"name": "BDomain",
"data": "domain.com"
},
{
"name": "Charts",
"data": "2"
},
{
"name": "Compress",
"data": "0"
},
{
"name": "CompressJ",
"data": "0"
}
]
Теперь я хотел бы вернуть этот csv из моего json, однако цепочки | ConvertFrom-Json | ConvertTo-CSV не работают, и мне любопытно, почему бы и нет?
Ответы
Чтобы дополнить полезный ответ Стивена кратким резюме и перекрестным обзором:
В PowerShell [Core] v7 + не требуется дополнительных усилий: добавление
| ConvertFrom-Json | ConvertTo-Csvв код работает как есть.В Windows PowerShell и PowerShell [Ядро] v6.x , вам нужно силы перечисления на
ConvertFrom-Jsonвыходе «S для того , чтобыConvertTo-Csvработать правильно, потому что, против обычного поведения PowerShell, вConvertFrom-Jsonвыводит массив JSON в целом, как единый объект к трубопроводу .Это необычное поведение вызвало изменение версии 7 + - см. Этот ответ для получения справочной информации.
Самый простой способ перечисления силы - то есть , чтобы отправить элементы AN / коллекции выхода-как-целое массива по одному к трубопроводу для использования
(...), в группировке оператора .
# Works in all PowerShell versions, but in v7+ the (...) is no longer necessary.
(
"name,data
Play,http://{gho}.domain.com/
BDomain,domain.com
Charts,2
Compress,0
CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json |
ConvertFrom-Json
) | ConvertTo-Csv -NoTypeInformation
Это дает:
"name","data"
"Play","http://{gho}.domain.com/"
"BDomain","domain.com"
"Charts","2"
"Compress","0"
"CompressJ","0"
Результатом ConvertFrom-Jsonявляется единственный массив, который передается по конвейеру как таковой. Это следствие того, как ConvertFrom-Jsonпишется вывод. Вероятно, он собирает все и выводит массив в одной Write-Outputкоманде (неявной или иной) вместо того, чтобы передавать каждый объект по конвейеру по мере их создания. Вероятно, это следствие того, как написан командлет, и, возможно, он был необходим.
Ваш текущий код, вероятно, генерирует CSV, например:
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
"5","5","5","1","System.Object[]","False","True","False"
Это свойства массива, а не объекты в нем. Один из способов обойти это - просто запарковать данные в переменной:
$Json = "name,data Play,http://{gho}.domain.com/ BDomain,domain.com Charts,2 Compress,0 CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json # Now you can convert back to csv without issue: $Json = $Json | ConvertFrom-Json $Json | ConvertTo-Csv -NoTypeInformation
Примечание: если вы отправляете $ Json напрямую
$Json | ConvertFrom-Json | ConvertTo-Csv..., возможно, у вас такая же проблема.
Итерации по объектам Json тоже, кажется, работают:
$Json = "name,data Play,http://{gho}.domain.com/ BDomain,domain.com Charts,2 Compress,0 CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json $Json |
ConvertFrom-Json |
ForEach-Object{ $_ } |
ConvertTo-Csv -NoTypeInformation
Благодаря @notjustme вы можете сократить это, (...)например:
($json | ConvertFrom-Json) | ConvertTo-Csv
Примечание: исправлено на ответ mklement0 .
Все эти варианты по сути заключаются в размещении массива перед трубой, чтобы обойти внутреннее поведение ConvertFrom-Json
Опять же, не уверен на 100%, почему ConvertFrom-Json ведет себя именно так. Я обновлю дополнительную информацию, когда найду более формальное объяснение.