此PShell代码在PS shell和cmd.exe shell中运行时似乎有不同的结果。这些运行在Windows 7 Professional上。
PS C:\src\t\rd> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 0 10586 117
PS C:\src\t\rd> Get-Content .\prodlist.txt
123
456
789
345
221
PS C:\src\t\rd> Get-Content .\rd2.ps1
$orgfile = 'photo.main.jpg'
$prodfile = '.\prodlist.txt'
$replpat = '[^\.]*(.*)','$1'
Get-Content -PSPath $prodfile |
ForEach-Object {
$orgfile -replace $replpat | Out-Null
Copy-Item -Path $orgfile -Destination "$_$($matches[1])" -WhatIf
}
PS C:\src\t\rd> .\rd2.ps1
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\123.main.jpg".
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\456.main.jpg".
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\789.main.jpg".
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\345.main.jpg".
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\221.main.jpg".
这是预期的结果。
但是,在cmd.exe shell中运行时,似乎$ matches变量不会保留到下一个语句中。
C:>powershell -NoProfile -Command $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 0 10586 117
17:12:41.25 C:\src\t\rd
C:>powershell -NoProfile -File .\rd2.ps1
Cannot index into a null array.
At C:\src\t\rd\rd2.ps1:8 char:52
+ ... Copy-Item -Path $orgfile -Destination "$_$($matches[1])" -What ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\123".
Cannot index into a null array.
At C:\src\t\rd\rd2.ps1:8 char:52
+ ... Copy-Item -Path $orgfile -Destination "$_$($matches[1])" -What ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
What if: Performing the operation "Copy File" on target "Item: C:\src\t\rd\photo.main.jpg Destination: C:\src\t\rd\456".
...
当我转向Windows 10系统时,我在PowerShell中使用相同的失败结果:
5.1.15063..674 PS shell
5.1.15063..674 cmd.exe shell
6.0.0.beta8 PS shell
为什么$ matches变量在下一个语句中无效? 为什么在PS shell和cmd.exe shell中执行的方式不同?
答案 0 :(得分:0)
我无法解释这种行为,但为什么首先采取这种错综复杂的方法呢?这样的事情会更清晰,更直接:
$pattern = '^[^.]*'
$replacement = ''
Get-Content $prodfile | ForEach-Object {
$suffix = $orgfile -replace $pattern, $replacement
Copy-Item -Path $orgfile -Destination "${_}${suffix}" -WhatIf
}
或者像这样,如果你想在循环中用搜索和替换字符串定义为变量:
{{1}}
答案 1 :(得分:0)
就像@AnsgarWiechers的回答一样,这并不能解释不同PowerShell环境中的不同行为。但是,它确实展示了一些有效的方法。
核心问题是使用-replace
而不是-match
。使用-match
会有效,但Ansgar认为这项工作最好在处理内容之前完成一次。
$orgfile = 'photo.main.jpg'
$prodfile = '.\prodlist.txt'
$replpat = '[^\.]*(.*)'
Get-Content -PSPath $prodfile |
ForEach-Object {
$orgfile -match $replpat | Out-Null
Copy-Item -Path $orgfile -Destination "$_$($matches[1])" -WhatIf
}