PowerShell中如何将JSON字符串转为JSON对象存入JSON数组?
PowerShell读取JSON文件并将内容作为JSON对象嵌入输出
问题描述
编写PowerShell脚本读取JSON文件时,通过Get-Content -Path $_.FullName将文件内容以字符串形式读取并存储到JSON数组中,但希望Contents字段是JSON对象而非JSON字符串的转义表示。
当前输出
[ { "LastWriteTime": "2023-03-07T15:22:07.8269947-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-07-202100Z_1678220527823.json", "Contents": "{\"a\":12345,\"b\":\"This is a test\\nof wills.\\n\",\"c\":[\"ABC006\",\"ABC502\",\"ABC503\"]}" }, { "LastWriteTime": "2023-03-08T15:18:58.4251682-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-08-201800Z_1678306738418.json", "Contents": "{\"a\":23456,\"b\":\"To\\nstack overflow\\n\",\"c\":[\"ABC006\",\"ABC502\",\"ABC503\"]}" }, { "LastWriteTime": "2023-03-09T15:06:18.6890386-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-09-200600Z_1678392378684.json", "Contents": "{\"a\":34567,\"b\":\"or not to\\nstack overflow\\nthat is the question.\\n\",\"c\":[\"ABC006\",\"ABC502\",\"ABC503\"]}" } ]
期望输出
[ { "LastWriteTime": "2023-03-07T15:22:07.8269947-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-07-202100Z_1678220527823.json", "Contents": {"a":12345,"b":"This is a test\nof wills.\n","c":["ABC006","ABC502","ABC503"]} }, { "LastWriteTime": "2023-03-08T15:18:58.4251682-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-08-201800Z_1678306738418.json", "Contents": {"a":23456,"b":"To\nstack overflow\n","c":["ABC006","ABC502","ABC503"]} }, { "LastWriteTime": "2023-03-09T15:06:18.6890386-05:00", "FullName": "\\server\d$\Program\logs\alerts\2480702_2023-03-09-200600Z_1678392378684.json", "Contents": {"a":34567,"b":"or not to\nstack overflow\nthat is the question.\n","c":["ABC006","ABC502","ABC503"]} } ]
原脚本片段
$rx = -join ($id, "_.*\.json") $dir = -join ("\\", $machine, "\d$\\", $appname, "\logs\alerts") $answer = [System.Collections.ArrayList]@() foreach ($machine in $machines) { $arr = Get-ChildItem $dir -Recurse | Where-Object { $_.Name -match $rx } | Select-Object @{ n = 'LastWriteTime'; e = { $_.LastWriteTime } }, @{ n = 'FullName'; e = { $_.FullName } }, @{ n = 'Contents'; e = { Get-Content -Path $_.FullName } } } $null = $answer.Add($arr) $answer | Sort-Object { $_.LastWriteTime -as [datetime] }
解决方案
核心是将读取到的JSON字符串转换为PowerShell对象,这样在最终序列化输出时,该对象会被转为JSON对象而非转义字符串。同时修正原脚本中的路径定义和集合添加逻辑,避免错误:
$rx = -join ($id, "_.*\.json") $answer = [System.Collections.ArrayList]@() foreach ($machine in $machines) { # 将路径定义移至foreach内部,确保$machine变量已赋值 $dir = -join ("\\", $machine, "\d$\", $appname, "\logs\alerts") $arr = Get-ChildItem $dir -Recurse | Where-Object { $_.Name -match $rx } | Select-Object @{ n = 'LastWriteTime'; e = { $_.LastWriteTime } }, @{ n = 'FullName'; e = { $_.FullName } }, # 读取完整字符串并转为PowerShell对象 @{ n = 'Contents'; e = { Get-Content -Path $_.FullName -Raw | ConvertFrom-Json } } # 用AddRange添加集合元素,避免嵌套数组 $null = $answer.AddRange($arr) } # 排序后转为JSON,指定深度避免结构截断 $answer | Sort-Object { $_.LastWriteTime -as [datetime] } | ConvertTo-Json -Depth 10
关键说明
Get-Content -Raw:读取整个文件为单一字符串,避免默认按行返回字符串数组导致的解析失败;ConvertFrom-Json:将JSON字符串转为PowerShell自定义对象,后续序列化时会自动转为原生JSON对象;AddRange:替代原脚本的Add方法,避免将整个集合作为单个元素存入列表;-Depth 10:解决ConvertTo-Json默认深度不足导致的嵌套结构截断问题,可根据实际JSON结构调整数值。
内容的提问来源于stack exchange,提问作者gknauth
相关产品推荐
相关产品推荐

