Если вы не укажете второй (длина) параметр для функции 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)
будет работать, но в этом случае это излишне.
РЕДАКТИРОВАТЬ Учитывая комментарии ОП, я проверил еще несколько и действительно ... Кажется, есть проблема с передачей результатов из Get-ChildItem
непосредственно в командлет Rename-Item
.(Я использую Powershell 5.1)
Кажется, вам нужно захватить элементы из командлета Get-ChildItem
и выполнить итерацию этой захваченной коллекции, чтобы переименовать файлы.В противном случае некоторые файлы могут быть обработаны и переименованы несколько раз.
Вы можете сначала собрать коллекцию файлов в переменную, например, так:
$files = Get-ChildItem -File
foreach($file in $files) { $file | Rename-Item -NewName $file.Name.SubString(4)}
Или заключив в нее часть Get-ChildItem
в скобках как PetSerAl предложил:
(Get-ChildItem -File) | Rename-Item -newname { $_.Name.SubString(4) }
Я нашел объяснение этому в этом ответе :
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.