PowerShell重命名项子字符串

时间:2019-02-03 07:07:35

标签: powershell

我有一个具有以下命名约定的文件目录:'###一堆随机名称.txt',我想将文件重命名为减去'###'的相同名称。

应该足够简单:

Get-ChildItem -File | Rename-Item -newname { $_.Name.SubString(4,$_.Name.Length) }

但是我得到“索引和长度必须引用字符串中的位置。”

我通过以下方式验证Name.Length:

Get-ChildItem -File | select Name, @{ N='name length';E={$_.Name.Length) } }

$ _。Name.Length返回目录中每个文件的正确int值

当我尝试这样做时:

Get-ChildItem -File | select Name, @{N='name length';E={ $_.Name.SubString(4,$_.Name.Length) } }

“名称长度”列为空

为什么子字符串不像$ _。Name.Length?我在这里想念什么?

3 个答案:

答案 0 :(得分:1)

如果您没有为Substring()函数指定第二个(长度)参数,它将返回从第一个参数(字符索引)获取的字符串的其余部分,因此您可以简单地执行以下操作:

Get-ChildItem -File | ForEach-Object { $_ | Rename-Item -NewName $_.Name.SubString(4)}

您得到的错误"Index and length must refer to a location within the string."表示第二个参数(所需长度)超过了字符串的总长度,因为您要截断前4个字符。

$_.Name.SubString(4,$_.Name.Length - 4)

可以工作,但是在这种情况下会显得过大。


编辑

考虑到OP的评论,我进行了更多测试,的确是……...将Get-ChildItem的结果直接传递到Rename-Item cmdlet似乎存在问题。 (我正在使用Powershell 5.1)

似乎您需要捕获来自Get-ChildItem cmdlet的项目并迭代捕获的集合,以便重命名te文件。否则,某些文件可能会被处理和重命名多次。

您可以像这样首先捕获变量中的文件集合:

$files = Get-ChildItem -File
foreach($file in $files) { $file | Rename-Item -NewName $file.Name.SubString(4)}

或者按照建议PetSerAlGet-ChildItem放在括号中:

(Get-ChildItem -File) | Rename-Item -newname { $_.Name.SubString(4) }

我在this answer中找到了对此的解释:

There appears to be a bug that can cause bulk file renaming to fail under certain conditions. If the files are renamed by piping a directory listing to Rename-Item, any file that's renamed to something that's alphabetically higher than its current name is reprocessed by its new name as it's encountered later in the directory listing.

答案 1 :(得分:0)

可以使用SubString来代替Remove

Get-ChildItem -File | Rename-Item -NewName { $_.Name.Remove(0,4) }

答案 2 :(得分:0)

另一种解决方案,该解决方案可以在所有地方检查#

Get-ChildItem -Path E:\temp\*#*  | Rename-Item -NewName  { $_.fullname.replace('#','') }