แปลงเป็น 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 ไม่ทำงานและฉันสงสัยว่าทำไมไม่
คำตอบ
เพื่อเสริมคำตอบที่เป็นประโยชน์ของ Stevenด้วยบทสรุปที่กระชับและมุมมองข้ามฉบับ:
ในPowerShell [Core] v7 +ไม่จำเป็นต้องใช้ความพยายามเพิ่มเติม: การต่อท้าย
| ConvertFrom-Json | ConvertTo-Csvโค้ดของคุณจะทำงานได้ตามที่เป็นอยู่ในWindows PowerShell และ PowerShell [หลัก] v6.xคุณจะต้องแจงนับแรงของ
ConvertFrom-Jsonการส่งออกของเพื่อให้ConvertTo-Csvการทำงานได้อย่างถูกต้องเพราะกับพฤติกรรมปกติ PowerShell ของConvertFrom-Jsonเอาท์พุทอาร์เรย์ JSON เป็นทั้งเป็นวัตถุเดียวเพื่อท่อ .เป็นความจริงที่ว่าพฤติกรรมนี้ผิดปกติที่แจ้งให้เกิดการเปลี่ยนแปลง v7 + - ดูคำตอบนี้สำหรับข้อมูลพื้นฐาน
วิธีที่ง่ายที่สุดในการบังคับใช้การแจงนับ - คือการส่งองค์ประกอบผลผลิต-as-a-ทั้งอาร์เรย์ / คอลเลกชันหนึ่งโดยหนึ่งไปยังท่อคือการใช้งาน
(...)ที่ผู้ประกอบการจัดกลุ่ม
# 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คำสั่งเดียว(โดยนัยหรืออย่างอื่น) แทนที่จะสตรีมวัตถุแต่ละชิ้นไปตามท่อเมื่อสร้างขึ้น อาจเป็นผลมาจากวิธีการเขียน 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
อีกครั้งไม่แน่ใจ 100% ว่าทำไม ConvertFrom-Json จึงทำงานในลักษณะนี้ ฉันจะอัปเดตข้อมูลเพิ่มเติมเมื่อพบคำอธิบายที่เป็นทางการมากขึ้น