Powershell ForEach-Object 多次处理目录中的文件

Lad*_*ish 2 powershell foreach-object

我有一系列文件,它们都是从基本系统导出的(补救措施)。默认情况下,它们在文件名之前有 32 个字符的 ID 相关信息。我想把这些字符去掉。然而,这样做也会导致重复,所以我需要一种方法来重命名它们而不创建重复。

例子:

CWL000000004901-z2AF 工作日志01-RFP 2012 01 获奖推荐.pdf

CWL000000004716-z2AF 工作日志01-Computrace 2009 年 11 月.pdf

CWL000000006007-z2AF 工作日志01-Computrace 2009 年 11 月.pdf

(删除前面的字符后,后 2 个将相同)

$i = 1
Get-ChildItem -Path "C:\temp\Remedy Contract Attachments\Output\CTR_WorkLog_test1_a" | 
ForEach-Object -Process {
    $NewName = $_.BaseName.Substring(32)
    $NewName2 = $NewName + "_" + $i + $_.Extension
    Rename-Item $_.FullName -NewName $NewName2
    $i++
 }
Run Code Online (Sandbox Code Playgroud)

这是我目前的代码。

似乎只要总字符数小于 64 就可以,

Computrace_Nov_2009_156.pdf

Computrace_Nov_2009_157.pdf

但随后它似乎会重复处理其余部分,就像这样

ietor_127_502.pdf

该文件夹中只有 394 个文件。

我从 PowerShell 学到的大部分内容都是从这里学到的,但我绝对被难住了。为什么它要多次处理文件?它会抛出一堆错误,表示它无法删除超过字符串中的字符数,因此显然它在最终崩溃之前仍在处理它们。但为什么?

或者有更好的方法来做到这一点吗?

我确信这是一件小事,我会因为整个下午都在与这些代码战斗而感到愚蠢。

谢谢!

mkl*_*nt0 6

  • 使用(...)分组运算符来确保预先收集所有输入文件。

    • 不这样做可能会导致已重命名的文件重新进入枚举
  • 为了提高效率,请直接通过管道连接到Rename-Item,并使用延迟绑定脚本块来动态确定新文件名。

    • 由于延迟绑定脚本块在调用者的子作用域中执行,因此需要一种解决方法来跨调用递增值 - 因此使用哈希表作为$i值。请参阅此答案以获取解释。
$i = @{ Value = 1 }
(Get-ChildItem -LiteralPath 'C:\temp\Remedy Contract Attachments\Output\CTR_WorkLog_test1_a') | 
  Rename-Item -NewName {
    $_.BaseName.Substring(32) + '_' + $i.Value++ + $_.Extension
  } -WhatIf 
Run Code Online (Sandbox Code Playgroud)

注意:上面命令中的-WhatIf公共参数预览操作。一旦您确定该操作将执行您想要的操作,请删除-WhatIf并重新执行。