PowerShell 5.1脚本向UTF-8 JSON插入版权符号显示异常求助
PowerShell更新JSON文件时版权符号显示异常问题
问题背景
我使用PowerShell 5.1.19041.1682编写了一个脚本(UTF-8带BOM编码),用于更新JSON配置文件的版权年份。工作流程为读取JSON文件、修改版权日期、重新保存,但更新后版权符号©在Visual Studio Code、SourceTree、Azure DevOps文件查看器中显示为�,仅在PowerShell和记事本中显示正常。原JSON文件为UTF-8编码。
复现内容
原JSON文件(info.json)
{ "CopyrightInfo": "Copyright © CompanyName 1992" }
PowerShell复现代码
$path = "./info.json" $a = Get-Content $path| ConvertFrom-Json $a.'CopyrightInfo' = "Copyright $([char]::ConvertFromUtf32(0x000000A9)) CompanyName $((Get-Date).Year)" $a | ConvertTo-Json | set-content $path
异常现象
更新后的JSON文件在部分工具中显示如下:
"CopyrightInfo": "Copyright � CompanyName 2022"
原因分析
PowerShell 5.1中,Set-Content默认使用系统默认的ANSI编码(而非UTF-8)保存文件。即便原JSON是UTF-8编码,修改后保存时会被转成ANSI编码,版权符号©不属于ANSI字符集,因此在以UTF-8编码解析文件的工具中会显示为乱码�。而记事本和PowerShell会自动适配编码显示,所以看起来正常。
解决方法
方法1:使用Set-Content指定UTF-8带BOM编码
$path = "./info.json" # 读取时指定UTF-8编码,确保原文件内容正确解析 $a = Get-Content $path -Encoding UTF8 | ConvertFrom-Json # 直接使用版权符号或[char]0xA9均可 $a.'CopyrightInfo' = "Copyright © CompanyName $((Get-Date).Year)" # 保存时强制指定UTF-8编码 $a | ConvertTo-Json | Set-Content $path -Encoding UTF8
备注:此方法生成的文件为UTF-8带BOM格式,大部分工具可正常识别,但部分严格要求无BOM的场景需使用下方方法。
方法2:使用.NET方法写入无BOM的UTF-8编码
$path = "./info.json" $a = Get-Content $path -Encoding UTF8 | ConvertFrom-Json $a.'CopyrightInfo' = "Copyright $([char]0xA9) CompanyName $((Get-Date).Year)" $jsonContent = $a | ConvertTo-Json # 调用.NET API写入无BOM的UTF-8文件,与原JSON编码一致 [System.IO.File]::WriteAllText($path, $jsonContent, [System.Text.Encoding]::UTF8)
备注:此方法生成的文件为无BOM的UTF-8格式,完全匹配原文件编码,兼容所有支持UTF-8的工具。
内容的提问来源于stack exchange,提问作者Kagemand Andersen
相关产品推荐
相关产品推荐

