PowerShell의 JSON에서 CSV로 변환

Sep 23 2020

이것은 내 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"
}
]

이제 내 json에서 해당 csv를 가져오고 싶지만 | ConvertFrom-Json | ConvertTo-CSV가 작동하지 않는데 왜 안되는지 궁금합니다.

답변

1 mklement0 Sep 25 2020 at 05:11

간결한 요약 및 교차 버전 관점으로 Steven의 유용한 답변 을 보완하려면 다음을 수행하십시오.

  • 에서 PowerShell을 [코어] V7 + , 여분의 노력이 필요하지 않습니다 : 추가 | ConvertFrom-Json | ConvertTo-Csv-그대로 코드로하면 작동합니다.

  • 에서 의 Windows PowerShell 및 PowerShell을 [코어] v6.x , 당신은 필요 힘 열거 의 ConvertFrom-Json순서에의 출력 ConvertTo-CsvPowerShell을의 평소 행동에 대해, 때문에, 제대로 작동하려면 ConvertFrom-JsonJSON 배열 출력 전체를 하나의 개체로, 파이프 라인에 .

    • 이 동작은 v7 + 변경을 유발 한 비정상적인 사실입니다 . 배경 정보는 이 답변 을 참조하십시오 .

    • 열거를 강제하는 가장 간단한 방법, 즉 출력으로서의 전체 배열의 / 컬렉션 요소 를 파이프 라인 에 하나씩 보내는 방법 (...)은 그룹화 연산자 를 사용 하는 것입니다 .

# 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"
2 Steven Sep 22 2020 at 23:59

의 출력은 ConvertFrom-Json파이프 라인을 따라 전달되는 단일 배열입니다. 이것은 ConvertFrom-Json출력을 작성 하는 방법의 결과입니다 . Write-Output각 객체가 생성 될 때 파이프 라인 아래로 스트리밍하는 대신 모든 것을 수집하고 하나의 명령 (암시 적 또는 기타)으로 배열을 출력합니다 . 아마도 cmdlet 작성 방식의 결과이며 필요할 수 있습니다.

현재 코드는 다음과 같은 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

ConvertFrom-Json이 왜 이런 식으로 작동하는지 100 % 확실하지 않습니다. 좀 더 공식적인 설명을 찾으면 추가 정보로 업데이트하겠습니다.