PowerShell使用*通配符匹配带[]的路径报错如何解决
问题背景
需要批量复制HWMonitorPro生成的图片文件,软件的存储目录结构固定无法修改,规则如下:
- 日志根路径:
C:\Users\hugo\Documents\DossierTest\logs - 每次录制自动生成第一层子目录,命名格式为
[日期 时间],例如[JUN 13, 2022 - 11:06] - 日期目录下固定为设备名目录
[LAPTOP-P15V] - 设备目录下固定为分辨率目录
[1280x960] - 目标文件存储在分辨率目录下
最初编写的PowerShell脚本尝试用*通配符匹配所有日期目录,实现批量复制:
$C = "C:\Users\hugo\Documents\DossierTest\logs" copy-item $C'\*\`[LAPTOP-P15V`]\`[1280x960`]\789.txt' -Destination $C\test3
该脚本将*替换为具体日期目录名时可正常运行,但使用通配符时抛出错误:
Copy-Item : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard character pattern is not valid: [LAPTOP-P15V
故障原因
PowerShell中[和]是通配符规则里的范围匹配符(和正则里的字符集作用类似),原脚本的转义写法存在两个问题:
- 反引号(
`)是PowerShell的转义字符,但在单引号字符串中反引号会被识别为普通字符,根本没有起到转义方括号的作用 - 当路径中混合使用
*这类通配符时,PowerShell会将整段路径按通配符模式解析,未被正确转义的[会被识别为范围匹配的起始标记,由于找不到对应的闭合],直接抛出通配符格式非法的错误
解决方案
推荐使用逐目录枚举的写法,容错率最高,不会受特殊字符转义问题影响:
$logRoot = "C:\Users\hugo\Documents\DossierTest\logs" $destPath = Join-Path $logRoot "test3" # 提前创建目标目录,已存在时不会报错 New-Item -ItemType Directory -Path $destPath -Force | Out-Null # 枚举根目录下所有第一层的日期格式子目录 Get-ChildItem -Path $logRoot -Directory | ForEach-Object { # 拼接源文件完整路径,-LiteralPath参数会按字面量解析路径,不会把[]识别为通配符 $sourceFile = Join-Path $_.FullName "[LAPTOP-P15V]\[1280x960]\789.txt" if (Test-Path -LiteralPath $sourceFile) { Copy-Item -LiteralPath $sourceFile -Destination $destPath } }
如果需要用单条通配符命令实现,可以借助.NET方法自动转义固定路径段的特殊字符,避免手动转义出错:
$logRoot = "C:\Users\hugo\Documents\DossierTest\logs" $destPath = Join-Path $logRoot "test3" New-Item -ItemType Directory -Path $destPath -Force | Out-Null # 自动转义固定路径部分的所有通配符特殊字符 $fixedPathPart = [WildcardPattern]::Escape("\[LAPTOP-P15V]\[1280x960]\789.txt") $sourceMatchPattern = Join-Path $logRoot "*" | Join-Path -ChildPath $fixedPathPart Copy-Item -Path $sourceMatchPattern -Destination $destPath
注:如果需要复制的是图片文件,把代码里的
789.txt替换成实际的图片文件名匹配规则(比如*.png)即可。
内容的提问来源于stack exchange,提问作者Hugo
相关产品推荐
相关产品推荐

