如何修正PowerShell脚本批量清理畸形JSON文件的替换逻辑?
解决PowerShell批量修复畸形JSON文件的替换失效问题
我正在分析环境内的服务器数据,通过PowerShell获取数据并为每台服务器生成JSON文件。但部分JSON文件格式畸形,需要批量遍历所有文件,识别畸形文件并移除特定错误部分:开头的{"value": [ 以及结尾的, "Count": 数字 }。尝试使用-replace和String.Replace()均未成功,错误部分仍存在,求解决替换不生效的问题。
畸形JSON示例
{ "value": [ { "Server": "SERVERNAME", "Name": "SHARE", "ScopeName": "*", "Path": "", "Description": "", "ShareState": 1, "AvailabilityType": 0, "ShareRights": [ ], "ShareSddl": "", "ShareRoot": [ ], "TotalFileCount": 35, "TotalDirectoryCount": 47, "TotalFolderSizeBytes": "", "TotalFolderSizeInMB": "", "TotalFolderSizeInGB": "", "TreeSizeDirFailed": null, "TreeSizeFileFailed": null, "TreeErrorHistory": null } ], "Count": 10 // 这个数字会变化 }
测试脚本
$Files = Get-ChildItem -path "" $StartMatch = @" { "value": "@ $EndMatch = @" , !!!ROW!!! } "@ ForEach ($File in $Files){ Write-Host "■ Checking file: $File" $Contents = (Get-Content -Path "$File") if ($Contents.StartsWith($StartMatch)){ Write-Host "Match" -ForegroundColor Green #test print Write-Host "-Checking EOF... " -NoNewline if (($Contents | Select-Object -Last 3) -like "*Count*"){ Write-Host "Match" -ForegroundColor Green $EOFMatch = $EndMatch -replace "!!!ROW!!!", $Contents[$Contents.length - 2] Write-Host $EOFMatch -ForegroundColor Yellow $Contents = $Contents -replace $EOFMatch, "" $Contents #test print Break #testing only } }else{ Write-Host "No match"#test print } }
问题分析与解决方案
你的脚本替换失效主要有三个核心原因:
Get-Content默认返回数组:直接用数组调用StartsWith和-replace会逻辑出错——数组的StartsWith只检查第一个元素,而你的$StartMatch是多行文本,第一个元素仅为{,无法匹配;数组用-replace会逐个元素替换,无法处理跨多行的匹配。- 多行匹配未处理正则转义:
-replace默认是正则匹配,你用的多行字符串包含大括号、逗号等正则特殊字符,未转义会导致匹配失败。 - 结尾匹配逻辑不严谨:依赖最后3行包含
Count的判断容易误判,且未处理换行、空格的差异。
修正后的脚本
$targetPath = "你的JSON文件目录路径" $Files = Get-ChildItem -Path $targetPath -Filter *.json foreach ($File in $Files) { Write-Host "■ 正在处理文件: $($File.Name)" # 读取文件为完整字符串,保留所有换行和空格 $content = Get-Content -Path $File.FullName -Raw # 匹配畸形JSON的完整结构,捕获中间有效内容 $pattern = '^\s*\{"value":\s*\[(.*?)\],\s*"Count":\s*\d+\s*\}$' if ($content -match $pattern) { # 将捕获的有效内容包装为合法JSON数组 $fixedContent = "[$($matches[1])]" # 写回文件(如需备份可先复制原文件) $fixedContent | Set-Content -Path $File.FullName -Encoding utf8 Write-Host "✅ 文件修复完成" -ForegroundColor Green } else { Write-Host "❌ 文件格式不匹配,跳过" -ForegroundColor Red } }
脚本说明
-Raw参数:将文件内容读取为单个字符串,解决数组匹配的问题,支持跨多行的正则匹配。- 正则表达式逻辑:
^\s*:匹配开头任意空白字符(换行、空格都包含)。\{"value":\s*\[':精准匹配开头的{"value": [,允许中间有任意空格。(.*?):非贪婪捕获中间的有效服务器数据部分,避免过度匹配。\],\s*"Count":\s*\d+\s*\}$:匹配结尾的, "Count": 数字 },允许数字前后、大括号前有任意空格。
- 生成合法JSON:将捕获的有效内容用
[]包裹,直接生成标准的JSON数组格式。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

