You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell批量处理JSON文件时提示路径不存在/非法字符报错

问题根因
  • 报错核心是PowerShell默认的-Path参数会对传入路径做通配符解析,路径里的[]、隐藏的零宽控制字符、特殊符号都会被识别为通配符语法而非普通文件名,你之前处理的文件夹内文件名没有这类特殊字符所以运行正常,换目录后碰到带特殊字符的文件就直接触发路径非法、找不到文件的报错。
  • 原脚本直接在路径里拼接*.json通配符,进一步放大了解析冲突,就是你单独传报错文件路径时看到的Illegal characters in path错误来源。
  • 原脚本没有提前创建目标目录的逻辑,加上特殊字符导致的路径解析失败,部分文件根本没写入新目录,后续执行Select-String时自然报目标文件不存在。
  • 你从资源管理器复制的路径确实是真实存在的,但资源管理器不会显示文件名里的零宽控制字符,也不会提示方括号这类字符会被脚本解析器特殊处理,所以肉眼排查不出文件名差异。
修复方案
  • 枚举文件时不要把通配符写在-Path参数里,统一使用-LiteralPath参数传基础目录路径,这个参数会把传入内容完全作为字面量路径处理,不会做任何通配符转义,从根源规避特殊字符解析问题;文件后缀过滤改用-Filter参数实现。
  • 写入新文件前,先检查目标文件对应的父目录是否存在,不存在则自动创建,避免因目录缺失写入失败。
  • 所有文件操作cmdlet(Get-Content/Set-Content/Test-Path/Select-String等)传文件路径时,统一使用-LiteralPath参数,不要依赖默认的-Path参数解析。
  • 新文件路径不要用简单字符串替换生成,通过相对路径拼接的方式生成,避免原路径存在其他同名字符串时被误替换。
修正后的可运行代码
# 配置基础路径,不要带*.json后缀
$baseSourcePath = "C:\Users\jutrust\documents\MyFolder"
$baseTargetPath = "C:\Users\jutrust\documents\MyNewFolder"

# 用-LiteralPath枚举,-Filter指定json后缀,完全规避特殊字符解析问题
$files = Get-ChildItem -LiteralPath $baseSourcePath -Filter "*.json" -Recurse

foreach($file in $files)
{
    # 读取原文件内容,同样用-LiteralPath避免特殊字符问题
    $content = Get-Content -LiteralPath $file.FullName -Raw | ConvertFrom-Json
    # 按相对路径拼接新文件路径,避免字符串硬替换导致的路径错误
    $relativePath = $file.FullName.Substring($baseSourcePath.Length)
    $newFilePath = Join-Path -Path $baseTargetPath -ChildPath $relativePath
    # 提前创建新文件的父目录
    $newFileDir = Split-Path -Path $newFilePath -Parent
    if(-not (Test-Path -LiteralPath $newFileDir)){
        New-Item -ItemType Directory -Path $newFileDir -Force | Out-Null
    }
    # 写入格式化后的json
    ConvertTo-Json -InputObject $content -Depth 100 | Set-Content -LiteralPath $newFilePath
    # 检索指定文本,统一用字面量路径传参
    $filename = [System.IO.Path]::GetFileNameWithoutExtension($newFilePath)
    $line = Select-String -AllMatches -LiteralPath $newFilePath -Pattern "mytext"
}
补充排查

如果改完脚本仍有个别文件报非法路径错误,在循环内加一行命令打印文件名的字符编码,就能揪出肉眼看不到的非法控制字符:

# 打印文件名每个字符的Unicode编码,编码值小于32的就是不可见非法字符
$file.Name.ToCharArray() | ForEach-Object { [int]$_ }

找到对应文件后去掉文件名里的非法控制字符即可正常处理。

内容的提问来源于stack exchange,提问作者JuTrust

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:33:27