powershell - 重命名多个文件夹(有错误!)

标签 powershell

我是 PowerShell 新手,使用 ISE 编写了以下脚本,尝试将同一目录中的一堆文件夹重命名,这些文件夹的日期格式严格为 20201130 为 2020-11 -30(只需添加破折号) 该脚本还可以,但我有 3 个问题。

1- 当它运行时,它抛出了一堆与 Rename-Item 相关的错误 错误:

Rename-Item : Source and destination path must be different.
At line:13 char:25
+ ... ChildItem | Rename-Item -NewName { $_.Name -replace $file, $MyNewName ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (D:\Google Drive...Term 2\testings:String 
   ) [Rename-Item], IOException
    + FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.Renam 
   eItemCommand

2- 当我使用名为 (234567890) 的文件夹测试它时,它仍然有效,尽管该文件夹的长度不等于 8!

3- 当上述重命名发生时,结果名称是“1234-56-7890”,这很奇怪,因为 $MyNewName 应该结束有 2 个字符! $file.Substring( 6 , 2 )

脚本:

$FileNameArr_All = (Get-ChildItem).Name
$i = 0

foreach($file in $FileNameArr_All){
    
    if ( ($file -match "^\d+$") -and ($file.Length -eq 8) ){
    
        [string] $MyNewName = $file.Substring( 0 , 4 )+"-"+$file.Substring( 4 , 2 )+"-"+$file.Substring( 6 , 2 )
        
        #the actual renamining of the item, where the error is:
        Get-ChildItem | Rename-Item -NewName { $_.Name -replace $file, $MyNewName }

        $message = "the item " + $file + " has been renamed : " + $MyNewName
        Write-Output $message
        $i ++

        Write-Output $file.Length
    }
}
if ($i -eq 0){
    Write-Output "No mathcing items found."
}
else{
    $message2 = "total of items affected: " + $i
    Write-Output $message2
}

我知道内容很多,但这是我的第一篇文章,也是我的第一个脚本,我很感谢您对其中任何一点的帮助。
非常感谢:)

最佳答案

现有答案中有很好的信息,但让我从概念上概括它并提供更简化的解决方案:

  • 您正在循环遍历所有目录名称单独,但您试图重命名每个循环中的所有项目迭代,由于仅使用 Get-ChildItem - 无参数 - 作为 Rename-Item 的输入:

    • 获取子项 | Rename-Item ...所有文件和子目录发送到Rename-Item;您实际上正在尝试将它们全部重命名为现有名称(请参阅下一个要点),这对于文件来说是一个安静的无操作>,但会触发您在目录中看到的源路径和目标路径必须不同错误。
  • $MyNewName完整的新文件名,因此没有理由在上使用-replace原始目录名称:由于 $MyNewName 不是现有名称的子字符串,因此 $_.Name -replace $file, $MyNewName 实际上是 < em>no-op - 现有的 $_.Name 被传递。

    • 如果您要重命名单个项目,只需在delay-bind script block内传递$MyNewName - 而不是 ({ ... } ) - 就足够了。

但是,您可以简化您的解决方案以使用单个管道,其中包括使用 wildcard expression 来匹配的 Get-ChildItem 调用感兴趣的目录,以及带有延迟绑定(bind)脚本 block 的 Rename-Item 来插入 - 字符。通过基于正则表达式的 -replace operator 匹配项目的名称:

# Create two sample directories
$null = New-Item -Force -Type Directory '12345678', '87654321'

Get-ChildItem -Directory -Path ('[0-9]' * 8) |
  Rename-Item -NewName { $_.Name -replace '(.{4})(.{2})(.{2})', '$1-$2-$3'  } -Verbose

上面执行了所需的重命名,并且由于使用了 common -Verbose parameter ,打印了以下内容(为了可读性换行):

VERBOSE: Performing the operation "Rename Directory" on target "Item: ...\12345678 
         Destination: ...\1234-56-78".       
VERBOSE: Performing the operation "Rename Directory" on target "Item: ...\87654321
         Destination: ...\8765-43-21".

注意:

  • 如果您想要预览重命名操作,请将 common -WhatIf parameterRename-Item 结合使用。

  • 如果您需要知道是否有任何文件匹配并因此被重命名,请首先捕获变量中的 Get-ChildItem 调用:

    $files = Get-ChildItem -Directory -Path ('[0-9]' * 8)
    
    $files | Rename-Item -NewName { $_.Name -replace '(.{4})(.{2})(.{2})', '$1-$2-$3'  } -Verbose
    
    Write-Verbose -Verbose $(if ($files) { "$($files.Count) directories renamed." } else { 'No matching directories found.' })
    

关于powershell - 重命名多个文件夹(有错误!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64833471/

相关文章:

PowerShell Compare-Object 和 Export-Csv 导出错误数据

windows - 在 PowerShell v2 中打破 foreach 循环

c# - 如何在 Set-ADUser 中使用 "-replace"?

powershell - AAD PowerShell v2 Add-MsolRoleMember 等效项

c# - 我可以使用 C# 和 Powershell 做什么?

Powershell - 获取 AD 用户的姓名首字母

powershell - 如何将带有空格的参数作为数组传递给 Powershell 中的 RoboCopy?

windows - 在后台运行的启动脚本

powershell - 通过快捷键或命令行/shell 从 Windows 桌面运行 Power Automate 流程

powershell - 如何使 Validate-set 也适用于强制参数输入提示?