PowerShell文件匹配错误及未调用变量自动执行问题求助
问题1:PowerShell使用
-match误匹配文件的解决方法 我有如下PowerShell代码:
$MoveSheet0101AfterRender = get-ChildItem $Sheet01 -recurse | where {$_.name -match "Model 01-02 - $TodayDate"} | Move-Item -Destination (new-item -type directory -force ($OldSheets + $newSub)) -force -ea 0
这段代码本意是查找名称包含Model 01-02 - $TodayDate的文件并移动,但实际会误移动Model 01-03 - $TodayDate这类文件名的文件。换成-contains后又找不到任何文件,且不能用-eq(因为目标字符串只是文件名的一部分),该怎么解决?
解决办法
- 问题根源:
-match是正则表达式匹配,01-02中的-在正则里是表示范围的特殊字符,因此01-03也会被判定为匹配。 - 两种修复方案:
- 使用
-like通配符匹配(PowerShell原生匹配方式,无需转义特殊字符):
这里的$MoveSheet0101AfterRender = Get-ChildItem $Sheet01 -Recurse | Where-Object {$_.Name -like "*Model 01-02 - $TodayDate*"} | Move-Item -Destination (New-Item -Type Directory -Force ($OldSheets + $newSub)) -Force -ErrorAction 0*代表任意长度的任意字符,前后添加*即可匹配包含目标字符串的文件名。 - 若坚持用
-match,需用[regex]::Escape()转义正则特殊字符:
转义后$pattern = [regex]::Escape("Model 01-02 - $TodayDate") $MoveSheet0101AfterRender = Get-ChildItem $Sheet01 -Recurse | Where-Object {$_.Name -match $pattern} | Move-Item -Destination (New-Item -Type Directory -Force ($OldSheets + $newSub)) -Force -ErrorAction 0-会被当作普通字符处理,不会触发正则的范围匹配逻辑。
- 使用
问题2:未调用的PowerShell变量自动执行代码的原因
我还有一个变量$MoveSheet0103AfterRender,代码如下:
$MoveSheet0103AfterRender = get-ChildItem $Sheet01 -recurse | where {$_.name -eq "$ClientName - Modelo 01-03 - $TodayDate.txt"} | Move-Item -Destination (new-item -type directory -force ($OldSheets + $newSub)) -force -ea 0
发现即使没调用这个变量,它也会自动执行移动操作,删除该变量后原代码即可正常运行,这是为什么?
原因及解决方案
- 核心原因:PowerShell中变量赋值时,等号右侧的管道命令会立即执行,和后续是否调用变量无关。管道里的
Get-ChildItem、Move-Item都是执行性命令,赋值语句运行时,这些命令就会被执行,执行结果会被赋值给变量。 - 若想让代码仅在调用变量时执行,需将其定义为脚本块(用
{}包裹):
之后通过$MoveSheet0103AfterRender = { Get-ChildItem $Sheet01 -Recurse | Where-Object {$_.Name -eq "$ClientName - Modelo 01-03 - $TodayDate.txt"} | Move-Item -Destination (New-Item -Type Directory -Force ($OldSheets + $newSub)) -Force -ErrorAction 0 }& $MoveSheet0103AfterRender调用脚本块,里面的代码才会执行。
内容的提问来源于stack exchange,提问作者Tyrone Hirt
相关产品推荐
相关产品推荐

