1

我有一个偶尔会不同步的谷歌驱动器文件夹。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
4

2 回答 2

2

尝试在 foreach-object 中包围后半部分,使用 Rename-Item 而不是 Replace-Item 等:

Get-ChildItem -Path "* (1)" -Recurse | ForEach-Object {Rename-Item -Path $_.Fullname -NewName $($_.Name.Replace(" (1)", "")) -WhatIf}
于 2017-03-23T20:03:11.767 回答
1

$_只是脚本块内的一个变量。和:

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

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

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

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

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

$_只是自由浮动的,你不能那样使用它,在脚本块之外它{}没有任何意义。而且您正在通过管道将输入文件输入管道,并尝试使用 -Path 指定它们,这会加倍 - 冲突和冗余。而且您使用的是替换而不是重命名。

所以在另一个答案中,nferrell 使用 ForEach 创建一个脚本块。并将文件通过管道传输到 ForEach,然后将它们的名称指定给 Rename-Item 的 -Path。

哪个有效,但它是冗长而迂回的。为什么要从管道中取出文件名并使用 ForEach 将它们随机移动到 cmdlet 的另一端,然后直接将它们放回原处?

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

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

于 2017-03-23T21:44:54.603 回答