2

Using Powershell 7, this works perfectly:

dir foo* | Rename-Item -Path {$_.Name} -NewName{$_.Name -replace 'bar-(.*)', 'bar-$1'}

This fails:

dir foo* | Rename-Item {$_.Name} {$_.Name -replace 'bar-(.*)', 'bar-$1'}

With the following error:

Rename-Item: A positional parameter cannot be found that accepts argument '$_.Name'.

Based on the docs here -Path is the first position of Rename-Item. Also, the following command works: Rename-Item 'foo-one' 'foo-one-one'. Why does the above failure happen?

4

1 回答 1

1

尽管您的示例代码实际上并未重命名任何文件(-replace 'bar-(.*)', 'bar-$1'将导致完全相同的名称。),但这里的主要问题是您{$_.Name}直接在Rename-Itemcmdlet 之后添加,这不是必需的,因为您已经通过管道传递 fileInfo 对象, 所以 now{$_.Name}被视为参数名称。
接下来,您忘记为 parameter 添加名称-NewName

foo*通过像你一样遍历一条路径-Path 'foo' -Recurse,其中有一个陷阱..

特别是在遍历许多文件并通过管道传递它们时,已经重命名的文件有可能再次被Get-ChildItem(alias dir) 拾取,然后将被重命名两次。

为了克服这个问题,将收集文件的部分放在括号之间,这样收集所有 FileInfo 对象就完成了,然后将其通过管道传递到下一个 cmdlet,如下所示:

(Get-ChildItem -Path 'foo' -File -Recurse) | 
 Rename-Item -NewName {$_.Name -replace 'bar-(.*)', 'baz-$1'} 

为清楚起见,这确实将名称的一部分从更改barbaz

于 2020-10-29T10:56:12.153 回答