由于您使用Get-ChildItem 而不将结果限制为文件(通过-File 开关),因此文件和目录都可以在输出项中.
虽然Rename-Item 会在文件被重命名为它当前拥有的同名时导致安静的无操作,在 目录 上尝试相同的操作会导致您看到的错误。
这适用于名称不包含子字符串'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),请参阅this answer。
如果您想预览可能发生的重命名操作,您可以将 -WhatIf common parameter 添加到 Rename-Item 调用中,它将为每个输入文件显示它将重命名为的内容。
但是,由于 delay-bind script block 传递给 -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
"