1

我正在使用 Powershell 并尝试返回目录的子项,该目录恰好是子目录,然后使用Rename-Itemcmdlet 将子目录名称重命名为其他名称。

我觉得下面的代码应该可以工作:

Get-ChildItem "C:\Users\Admin\Desktop\mydirectory\subdirectory" | Rename-Item -NewName {$_.Name -replace 'test'} 

但我收到此错误:

Rename-Item : Source and destination path must be different.

我在这里想念什么?提前致谢!

4

1 回答 1

3

由于您使用Get-ChildItem的结果不限于文件(通过-File开关),因此文件和目录都可以在输出项中。

如果将文件重命名为与其当前相同的名称Rename-Item,则会导致安静的无操作,但在目录上尝试相同的名称会导致您看到的错误。

这适用于名称不包含 substring 的所有项目'test'这种情况下,
-replace操作按原样传递输入字符串。

如果您的意图只是重命名文件,则解决方案是简单地添加-File开关

Get-ChildItem -File "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { $_.Name -replace 'test' } 

如果目录是(也)目标,就像您的情况一样,您需要明确过滤掉不会发生实际重命名的输入项

Get-ChildItem -Directory -Filter *test* "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { $_.Name -replace 'test' } 

-Filter *test*确保仅'test'输出包含该单词的子目录,从而保证发生实际重命名(但请注意,如果子目录的名是,则该命令将失败'test',因为这会使脚本块返回空字符串)。


如果您只是想将单个子目录重命名为固定的新名称,则根本不需要延迟绑定脚本块:

# NOTE: Works only if only a SINGLE subdirectory is returned.
Get-ChildItem -Directory "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName 'test'

如果您有多个子目录,并且您希望将序列号合并到新名称中,您确实需要一个延迟绑定脚本块:

$num = 0
Get-ChildItem -Directory "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { 'test' + ++(Get-Variable -Scope 1 num).Value } -WhatIf

这会将子目录重命名为test1, test2, ...
有关此技术的说明(需要Get-Variable调用),请参阅此答案


如果您想预览将要发生的重命名操作,您可以将-WhatIf公共参数添加到Rename-Item调用中,这将为每个输入文件显示它将被重命名为的内容。

但是,您必须从输出中推断出没有发生实际重命名的情况,因为传递的延迟绑定脚本块-NewName返回与以前相同的名称

例如,一个名为的输入文件foo不会重命名,因为'foo' -replace 'test'返回'foo'未修改,它-WhatIf会显示如下(为可读性添加了换行符) - 请注意目标和目标路径是如何相同的:

What if: Performing the operation "Rename File" on target "
Item: C:\path\to\foo 
Destination: C:\path\to\foo
"
于 2021-02-24T22:50:29.893 回答