Использование 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
Другие вопросы по тегам