Использование Powershell для изменения имен файлов
Когда изменение имен файлов стало настолько сложным?? Все, что я хочу сделать, это добавить «_a» в каталог файлов (без расширения).
Не работает следующее:
Rename-Item -newname { $_BaseName + '_a' } -whatif
Rename-Item : Cannot evaluate parameter 'NewName' because its argument is specified as a script block and there is no
input. A script block cannot be evaluated without input.
At line:1 char:22
+ Rename-Item -newname { $_BaseName + '_a' } -whatif
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.RenameItemCommand
затем:
Rename-Item -Path C:\users\r-waibel\Downloads\Mar723_pod3-m $_.basename -Newname ($_.basename + "_a") -whatif
Rename-Item : A positional parameter cannot be found that accepts argument '$null'.
At line:1 char:1
+ rename-item -Path C:\users\r-waibel\Downloads\Mar723_pod3-m $_.basena ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.RenameItemCommand
2 ответа
Как говорится в первом сообщении об ошибке, вам необходимо предоставить какие-то данные для-NewName {...}
работать.
Перенесите соответствующие элементы файла вRename-Item
и это сработает:
Get-ChildItem path\to\directory -File |Rename-Item -NewName { $_.BaseName + "_a" } -WhatIf
Позвольте мне добавить некоторую справочную информацию к эффективному решению Матиаса Р. Джессена :
Автоматическая переменная имеет значимое значение только внутри блоков скрипта (
{ ... }
), и чаще всего относится к текущему входному объекту, полученному через конвейер .Блок сценария, переданный в ваш
Rename-Item -NewName { $_BaseName + '_a' } -WhatIf
Команда представляет собой так называемый блок сценария с задержкой привязки , который, следовательно, действительно требует ввода конвейера :Обратите внимание, что блоки сценариев с привязкой к задержке работают только с параметрами, которые явно предназначены для привязки к входным данным конвейера (и что они не должны иметь тип
[script block]
или[object]
).По сути, вместо предоставления статического значения вы передаете фрагмент кода , который оценивается для каждого входного объекта конвейера и, следовательно, позволяет вычислять динамические значения для каждого входного объекта.
Если входные данные конвейера отсутствуют , команда не сможет работать, и вы получите сообщение об ошибке, включающее
Cannot evaluate parameter 'NewName' because its argument is specified as a script block and there is no input.
Напротив,
-NewName ($_.basename + "_a")
передает (в конечном счете) статическое значение в-NewName
; то есть выражение вычисляется один раз заранее , и его результат передается как статическое значение в параметр.По причинам, изложенным выше,
$_
не имеет значимой ценности в этом контексте; это так, тоже так, и общий результат просто_a
.Однако, поскольку вы также пытались использовать
$_.basename
в качестве дополнительного, позиционного аргумента
(rename-item -Path C:\users\r-waibel\Downloads\Mar723_pod3-m $_.basename -Newname ($_.basename + "_a") -whatif
), вызов фундаментально сломался из-за этого аргумента (значение которого оказывается$null
) не признаётся.Вот какое сообщение об ошибке
A positional parameter cannot be found that accepts argument '$null'.
указывает.Чтобы решить вашу задачу без блока сценария с задержкой привязки (последний предпочтительнее), но без необходимости жестко запрограммировать имя входного файла, вам понадобится aux. пользовательская переменная; например:
$file = Get-Item -LiteralPath C:\users\r-waibel\Downloads\Mar723_pod3-m $file | Rename-Item -NewName ($file.BaseName + '_a') -WhatIf
Вышеупомянутое - более громоздкое, только для одного файла - эквивалентно использованию блока сценария с задержкой привязки следующим образом:
Get-Item -LiteralPath C:\users\r-waibel\Downloads\Mar723_pod3-m | Rename-Item -NewName { $_.BaseName + '_a' } -WhatIf
Что касается:
Все, что я хочу сделать, это добавить «_a» в каталог файлов (без расширения).
Используя гибкость блоков сценариев с привязкой к задержке, описанную выше, это так же просто, как передача вывода из Get-ChildItem
вызов, который выводит все файлы для переименования в вашRename-Item
вызов:
Get-ChildItem -File -LiteralPath C:\users\r-waibel\Downloads\ |
Rename-Item -NewName { $_.BaseName + '_a' } -WhatIf