Powershell ConvertFrom-JSON到csv文件

时间:2017-10-07 02:24:51

标签: json powershell csv

我搜索过使用Powershell将复杂的json(嵌入式数组)转换为csv文件的示例。目的是接受json数据 进入MSAccess数据库。 MSAccess不提供执行此操作的内在功能。我是Powershell和json的新手,但我确实发现了引起我兴趣的ConvertFrom-JSON cmdlet。 我找到的最佳信息

  

iRon的展平对象功能

回应这篇文章

  

PowerShell convert nested JSON array into separate columns in CSV file

虽然这个函数可以创建单个csv,但是如果json中有嵌入式数组,我有兴趣创建多个csv文件。我们的想法是为每个级别的数据创建一个csv文件。级别2和更低级别将要求链接字段(id / name)用作level1中的主键,以及level2中的外键。 level2中的PK字段将作为外键包含在level3中,依此类推。由于Access可以将csv数据导入到表中,我的感觉是将数据转换为“规范化”的csv文件将是将json数据导入MSAccess数据库的可重复方法。

关于我的目标和Flatten-Object功能,我正在寻找以下建议/方向:

  • 可以调整/用于识别功能
  • json文件中的级别,
  • 为每个级别创建一个csv 要关联的可选择的PK字段
  • 以标准化方式导入MSAccess的csv数据文件??

我确实意识到每个json文件都需要一些人工干预。所以我正在寻找一种简化工作并且可重复的方法。

我创建了一个简单的脚本来获取一个简单的json文件(没有嵌入式数组)并将其转换为CSV。我在vba中使用了Shell命令来执行PS脚本。

    <#CarsBasic.ps1
.DESCRIPTION
This script takes the cars.json file and reads it into memory
Converts it from Json, then selects id,manufacturer,year from the result
and exports the data to C:\Programs\CarsJack.csv as a csv file with header
#>
 (Get-Content C:\Programs\MendipDataSystems\JSONParser\Files\Cars.json -Raw | 
 ConvertFrom-Json)  |Select id,manufacturer,year | 
  Export-CSV  c:\programs\CarsJack.csv -NoTypeInformation

提前致谢。

我已根据iRon的请求/评论对此帖进行了调整。

示例具有Squad,SquadMember和SquadMemberPower级别的json文件。我想得到一个有Squad信息的Squad.csv,一个有Squadname和每个成员详细信息的SquadMember.csv,以及一个SquadmemberPower csv,它有SquadName和成员名称,标识该Power所属的人。实际上,这3个csv文件将作为3个规范化表加载到MSAccess中。这是我的测试用例,但我想要一个更通用,可重用的方法 - 如果可能的话。这是MultiSquad.json

[{
    "squadName": "Super hero squad Alpha",
    "homeTown": "Metro City",
    "formed": 2016,
    "secretBase": "Large tent in the forest",
    "active": "True",
    "members": [{
        "name": "Molecule Man",
        "age": 29,
        "secretIdentity": "Dan Jukes",
        "powers": ["Radiation resistance",
        "Turning tiny",
        "Radiation blast"]
    },
    {
        "name": "Madame Uppercut",
        "age": 39,
        "secretIdentity": "Jane Wilson",
        "powers": ["Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"]
    },
    {
        "name": "Eternal Flame",
        "age": 1000000,
        "secretIdentity": "Unknown",
        "powers": ["Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"]
    }]
},
{
    "squadName": "Second squad Baker",
    "homeTown": "Metro Toronto",
    "formed": 2017,
    "secretBase": "CN tower",
    "active": "True",
    "members": [{
        "name": "Kathleen Wynne",
        "age": 49,
        "secretIdentity": "Cyan Arrah",
        "powers": ["XRay vision",
        "Invisibility",
        "Radiation blast"]
    },
    {
        "name": "Madame Butterfly",
        "age": 27,
        "secretIdentity": "Iman Angel",
        "powers": ["Magical hearing",
        "Fantastic ideas"]
    },
    {
        "name": "Gassy Misty Cloud",
        "age": 1000,
        "secretIdentity": "Puff of Smoke",
        "powers": ["Immortality",
        "Heat and Flame Immunity",
        "Impeccable hearing",
        "Xray Vision",
        "Able to jump tall buildings",
        "Teleportation",
        "Intergalactic travel"]
    }]
}]

预期输出:3个csv文件

1)带有字段的Squad.csv “squadName”, “家乡”, “形成”, “secretBase”, “活性”

2)SquadMembers.csv包含字段 “squadName”, “姓名”, “年龄”, “secretIdentity”

3)SquadMemberPowers.csv包含字段 “姓名”, “力量”

3 个答案:

答案 0 :(得分:1)

首先将json放到一个对象上:

$obj = Get-Content C:/input.json | ConvertFrom-Json

然后,您至少有两种方法可以选择所需的项目。

简单选择:

$obj | select squadName, homeTown, formed, secretBase, active | Convertto-csv > c:\squads.csv

复杂选择:

$members = $obj | foreach {

    $squadName = $_.squadName

    $_.members | foreach {
        [pscustomobject]@{
            squadName = $squadName
            name = $_.name
            age = $_.age
            secretIdentity = $_.secretIdentity
        }
    }   
}
$members | ConvertTo-Csv > c:\members.csv

$powers = $obj.members | foreach {
    $memberName = $_.name
    $_.powers | foreach {
        [pscustomobject]@{
            name = $memberName
            power = $_
        }
    }
}
$powers | ConvertTo-Csv > c:\powers.csv

答案 1 :(得分:1)

具体解决方案

假设$JSON包含您的JSON对象:

$Squads = @(); $SquadMembers = @(); $SquadMemberPowers = @()

ForEach ($Squad In $JSON) {
    $Squads += New-Object PSObject ($Squad | Select squadName, homeTown, formed, secretBase, active)
    ForEach ($member In $Squad.members) {
        $SquadMembers += New-Object PSObject ($member | Select @{label = "squadName" ;expression = {$Squad.squadName}}, name, age, secretIdentity)
        ForEach ($power In $member.powers) {
            $SquadMemberPowers += New-Object PSObject ($member | Select @{label = "name" ;expression = {$member.name}}, @{label = "powers" ;expression = {$power}})
        }
    }
}

$Squads | Export-CSV ".\Squad.csv" -NoTypeInformation
$SquadMembers | Export-CSV ".\SquadMembers.csv" -NoTypeInformation
$SquadMemberPowers | Export-CSV ".\SquadMemberPowers.csv" -NoTypeInformation

一般解决方案

关于一般(可重用)解决方案,我认为您的请求不够通用:在members级别,您有一个数组,其中包含要枚举的哈希表,在{ {1}}级别您希望转置数组,而不想从父级中提取一些不常见的属性(powers vs squadname。您可以在这里考虑引用第一个属性但是PowerShell中的哈希表并不总是保持有序,请参阅:Powershell Hashtables Key Order) 换句话说,对于一般解决方案,您需要提供如此多的参数,以便在比较特定的脚本中没有太大的附加价值,如上所述并更改它调整它的函数和变量。

答案 2 :(得分:0)

以下命令可用于使用分隔符“,”将csv数据分为几列。

例如:     Import-Csv“ C:\ Result.csv”-定界符“,” |排序对象_from -Unique | Export-csv“ C:\ FINAL_REPORT.csv”