如何用PowerShell仅替换JSON中以下划线开头的变量?脚本故障排查
问题排查与修复脚本
原脚本核心问题
- 嵌套属性无法正确解析:当
$tmp是test.value1这类字符串时,直接使用$_.$tmp会被当作单一属性名,而非嵌套对象的属性路径,导致无法修改目标值。 - 字符串替换逻辑不严谨:原
-replace '_',''会删除所有下划线,若变量名中间包含下划线(如_test_abc__value1)会被错误处理,应该仅移除开头的单个下划线。 - 重复IO操作:每次循环都读写文件,效率低下且可能引发数据覆盖问题。
修复后的脚本
# 定义需要替换的变量集合 $variables = @( [pscustomobject]@{Name='_test__value1'; Value='123'} [pscustomobject]@{Name='test2__value3'; Value='123'} [pscustomobject]@{Name='test__value1'; Value='123'} [pscustomobject]@{Name='_test2__value3'; Value='123'} ) # 一次性读取JSON文件并转换为对象 $jsonPath = "C:\temp\config.json" $jsonObj = Get-Content $jsonPath -Raw | ConvertFrom-Json foreach($variable in $variables) { # 仅处理名称以下划线开头的变量 if ($variable.Name -notlike '_*') { continue } # 处理变量名:先移除开头的单个下划线,再将__替换为.(属性路径分隔符) $propertyPath = $variable.Name -replace '^_', '' -replace '__', '.' $newValue = $variable.Value # 拆分属性路径,逐层访问嵌套对象 $currentObj = $jsonObj $pathSegments = $propertyPath -split '\.' for ($i = 0; $i -lt $pathSegments.Count; $i++) { $segment = $pathSegments[$i] # 如果是最后一段,赋值;否则进入下一层对象 if ($i -eq $pathSegments.Count - 1) { $currentObj.$segment = $newValue } else { $currentObj = $currentObj.$segment } } } # 一次性将修改后的对象写回JSON文件 $jsonObj | ConvertTo-Json -Depth 32 | Set-Content $jsonPath -Encoding UTF8
修复细节说明
- 嵌套属性处理:通过
-split '\.'将属性路径拆分为数组(如test.value1拆为test和value1),然后逐层遍历对象,最终定位到目标属性进行赋值。 - 字符串替换优化:使用
^_正则表达式仅匹配开头的单个下划线,避免误删变量名中间的下划线;再将__替换为.作为路径分隔符。 - 批量IO操作:仅在脚本开始读取一次文件,所有修改完成后再写入一次,提升效率并避免多次读写可能导致的问题。
- 逻辑优化:将不符合条件的变量直接
continue,代码更简洁易读。
内容的提问来源于stack exchange,提问作者Illya
相关产品推荐
相关产品推荐

