PowerShell:使用$ _.FullName.Replace重命名多个文件夹

时间:2017-03-23 19:53:43

标签: powershell rename-item-cmdlet

我有一个google驱动器文件夹偶尔会失去同步。 Google(或其他人)会将(1)追加到目录/文件名。然后它将删除原始目录,我将有一堆名为" xxx(1)"的文件夹和文件。

我一直在尝试编写一个powershell脚本,它将抓取目录树并重命名文件夹/文件,只需删除" (1)"一部分。我意识到这可能会导致一些冲突,但我希望能够使用脚本替换大部分冲突。我不关心目录结构,如果需要我会恢复,但这只是一种麻烦。

我已经尝试了几个PowerShell脚本,到目前为止我最接近的就是这个......

这将返回正确的新文件夹名称

Get-ChildItem -Path "* (1)" -Recurse | select { $_.FullName.Replace(" (1)", "")}

所以我试过了......

Get-ChildItem -Path "* (1)" -Recurse | Replace-Item -Path $_.FullName -Destination $_.FullName.Replace(" (1)", "") -WhatIf 

我收到错误"你不能在空值表达式上调用方法。"

You cannot call a method on a null-valued expression.
At line:1 char:1
+ Get-ChildItem -Path "* (1)" -Recurse | rename-item $_.FullName  $_.Fu ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

2 个答案:

答案 0 :(得分:1)

使用Rename-Item而不是Replace-Item等尝试围绕foreach-object的后半部分:

Get-ChildItem -Path "* (1)" -Recurse | ForEach-Object {Rename-Item -Path $_.Fullname -NewName $($_.Name.Replace(" (1)", "")) -WhatIf}

答案 1 :(得分:0)

$_只是scriptblock中的变量。用:

.. | select { $_.FullName.Replace(" (1)", "")}

你可以get-help select-object看到第一个位置参数是-Property,所以这是

的简称
.. | Select-Object -Property { $_.FullName.Replace(" (1)", "") }

现在您可以看到scriptblock通过管道获取文件,以$_访问它们并为输出计算新属性,$_对每个文件使用一次。当您尝试在第二行中使用相同的技术时:

.. | Replace-Item -Path $_.FullName -Destination $_.FullName.Replace(" (1)", "") -WhatIf 

$_只是自由浮动,你不能这样使用它,在{}脚本块之外它并不意味着什么。而你正在通过管道输入输入文件,并试图用-Path指定它们,这会加倍 - 冲突和冗余。而你正在使用Replace而不是Rename。

所以在另一个答案中,nferrell使用ForEach来创建一个scriptblock。并将文件传递给ForEach,然后将其名称指定给Rename-Item的-Path。

哪个有效,但它是罗嗦和迂回。为什么要将文件名从管道中取出并使用ForEach将它们循环到cmdlet的另一端,只是将它们直接放回来?

Get-ChildItem .. | Rename-Item -NewName { $_.Name.Replace(" (1)", "") }

文件通过管道进入,计算NewName。没有循环,没有加倍输入,没有