问题描述
我正在尝试加速我编写的程序,以便在新文件夹中制作图像副本。当它们碰巧都有一个标准化名称(例如 EA101、EA102 等)时,我已经开始使用它了。
我对 Powershell 还很陌生,但我对编程很熟悉。 我正在处理的问题出现在处理唯一名称时,例如 EA101-AG 或 EA105-ST 等。这是我的代码:
$variations = @("-1212W","-1216M","-1216W","-1818W","-1824M","-1824W","-2424W","-912M","-912W","-COAST","-MAG","-MBC","-MSWD","-ORN","-POST","-SWD","-TAG","-BMKR","-PIN","-KEY","-28W","-416W","-624W","-832W","-33BLK","-77BLK","-46BLK","-57BLK","-659BLK","-1212BLK","-1818BLK","-2424BLK","-912BLK","-1216BLK","-1824BLK","-630W","-630M")
foreach($n in 1..9){
copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\JunkFiles\PARK10$n.jpg"
trap{
continue;
}
foreach($m in 1..38) {
$v = $variations[$m]
copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\NewFiles\PARK10$n$v.jpg"
}
}
foreach($n in 10..99){
copy-Item "C:\Design Images for Web\PARK\PARK1$n.jpg" -Destination "C:\Design Images for Web\PARK\JunkFiles\PARK1$n.jpg"
foreach($m in 1..38){
$v = $variations[$m]
copy-Item "C:\Design Images for Web\PARK\PARK1$n.jpg" -Destination "C:\Design Images for Web\PARK\NewFiles\PARK1$n$v.jpg"
catch [System.Management.Automation.ItemNotFoundException] {break}
}
}
foreach($n in 200..999){
copy-Item "C:\Design Images for Web\PARK\PARK$n.jpg" -Destination "C:\Design Images for Web\PARK\JunkFiles\PARK$n.jpg"
foreach($m in 1..38){
$v = $variations[$m]
copy-Item "C:\Design Images for Web\PARK\PARK$n.jpg" -Destination "C:\Design Images for Web\PARK\NewFiles\PARK$n$v.jpg"
}
}
我尝试实施陷阱、中断、继续和尝试/捕获来跳过程序遇到非标准化名称的实例。我写了另一个脚本来处理这些。问题是,脚本 REALLY 不想停止在整个循环中运行并尝试为不存在的文件制作 38 个副本。考虑到有近 500 个文件具有相同的命名标准,运行时间太长。我无论如何都可以运行它,但我更感兴趣的是了解 Powershell 究竟是如何忽略这些行来让它停止的。我有一种设置工作,其中 Powershell 只运行一次内部循环:
foreach($n in 1..9){
copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\JunkFiles\PARK10$n.jpg"
trap{
continue;
}
foreach($m in 1..38) {
$v = $variations[$m]
copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\NewFiles\PARK10$n$v.jpg"
trap{break;}
catch{break;} # this Could also be continue,didnt make a difference...
}
}
然而,这对我不起作用,因为在不需要中断的情况下,它只在循环运行一次后就中断了。
解决方法
trap
语句仅对终止错误起作用,您的代码 - 至少在默认 $ErrorActionPreference
值为 'Continue'
- 不会 生产。
用于捕获终止错误的更灵活的替代结构是 try
/ catch
/ finally
语句:
- 这样的语句允许更细粒度的控制,而
trap
适用于整个封闭范围;实际上,trap
很少使用(不再使用)。
使用trap
OR try
/ catch
,最好使用后者。
如果你这样做,你也需要一个 try
子句 - 你不能只使用 catch
。
无论哪种方式,为了让您的代码产生终止错误,您必须将Copy-Item
命令产生的非终止错误提升到终止,使用以下方法之一:
要自动将非终止错误提升为终止错误范围,请按照
$ErrorActionPreference = 'Stop'
的建议在范围顶部使用 Santiago Squarzon。-
或者,通过将
-ErrorAction Stop
传递给各个 cmdlet 调用来选择性地执行此提升。
应用于您最后的代码片段:
# Promote all non-terminating errors to (script-)terminating ones.
$ErrorActionPreference = 'Stop'
foreach($n in 1..9){
try {
Copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\JunkFiles\PARK10$n.jpg"
} catch [System.Management.Automation.ItemNotFoundException] {
continue # continue with the enclosing `foreach` loop
}
foreach($m in 1..38) {
$v = $variations[$m]
try {
Copy-Item "C:\Design Images for Web\PARK\PARK10$n.jpg" -Destination "C:\Design Images for Web\PARK\NewFiles\PARK10$n$v.jpg"
} catch [System.Management.Automation.ItemNotFoundException] {
continue # continue with the enclosing `foreach` loop
}
}
}