使用Powershell重命名foreach循环中的文件-奇怪的行为

bihw5rsg  于 2023-01-13  发布在  Shell
关注(0)|答案(1)|浏览(140)

我正在重命名一个目录中的文件。重命名的方法是在文件名的开头加上一个字母,这取决于用户选择的选项(“F”或“O”)。本练习的一个可能的解决方案如下:

$Path="C:\app\SandBox\" 
    Get-ChildItem -Path $Path -Filter *.xlsx | ForEach-Object {
        $opt = Read-Host "Do you want modify (F) this file or not (O)?"
        $name=$_.name
        $PathFinal=$Path+$name
        if ($opt -eq "F") {
           $newName="F"+$name
           Rename-Item -NewName $newName -Path $PathFinal
            } 
        if ($opt -eq "O") { 
           $newName="F"+$name
           Rename-Item -NewName $newName -Path $PathFinal
            } 
        }

循环迭代的次数与目录中的文件数一样多。然而,当我尝试如下更改代码时:

$Path="C:\app\SandBox\" 
    Get-ChildItem -Path $Path -Filter *.xlsx | ForEach-Object {
        $name=$_.name
        $opt = Read-Host "$name - Do you want modify (F) this file or not (O)?"
        if ($opt -eq "O") {
            $name=$_.Name
            Rename-Item -NewName "O$name" -Path $Path$name
            } 
        if ($opt -eq "F") { 
            $name=$_.Name
            Rename-Item -NewName "F$name" -Path $Path$name
            } 
        }

事实证明,在某些情况下,循环会重复一次!如果我在文件夹中有两个文件,有时循环会重复三次。这可能是由于什么原因?

它应该迭代两次,但是迭代了三次。我想不出是什么原因,因为当引导时它应该只传递两个文件。

hmtdttj4

hmtdttj41#

它应该迭代两次,但是迭代了三次。我想不出是什么原因,因为当引导时它应该只传递两个文件。
Get-ChildItem通过询问与给定过滤器匹配的第一个文件来对抗文件系统,然后它继续询问操作系统"fileX之后的下一个匹配文件名是什么",直到操作系统说"没有更多文件"。
在这种情况下,A.xlsx在第一次迭代时被重命名为FA.xlsx,并且OS因此能够在 * 下一次 * 迭代之后回答问题:"B.xlsx之后的下一个匹配文件名是什么"与"下一个文件是FA.xlsx"。
要在启动脚本时仅枚举目录中已有的文件,请将对Get-ChildItem的调用放在子表达式或嵌套管道中:

$(Get-ChildItem -Path $Path -Filter *.xlsx) | ForEach-Object { ... }

这将强制PowerShell等待Get-ChildItem完成执行,然后再将第一个输出项发送到ForEach-Object-由于Get-ChildItem在重命名开始时已经"完成",因此您不会冒多次看到同一个文件的风险。

相关问题