Переименовать-элемент: исходный и целевой пути должны быть разными ошибками в Powershell

Я использую Powershell и пытаюсь вернуть дочерний элемент каталога, который оказывается подкаталогом, а затем использую командлет Rename-Item, чтобы переименовать имя подкаталога во что-то другое.

Я чувствую, что следующий код должен работать:

Get-ChildItem "C:\Users\Admin\Desktop\mydirectory\subdirectory" | Rename-Item -NewName {$_.Name -replace 'test'} 

Но я получаю эту ошибку:

Rename-Item : Source and destination path must be different.

Что мне здесь не хватает? Заранее спасибо!


person newman    schedule 24.02.2021    source источник
comment
Если вы пытаетесь настроить таргетинг только на папку C:\Users\Admin\Desktop\mydirectory\subdirectory, измените Get-ChildItem на Get-Item. Использование Get-ChildItem вернет все дочерние элементы этого каталога и попытается их переименовать. Get-Item вернет только элемент подкаталога   -  person Daniel    schedule 25.02.2021
comment
Спасибо за ответ @Daniel. В обычном сценарии Get-Item будет работать хорошо. Но в моем случае я буду запускать этот скрипт на многих разных компьютерах, и я не буду знать имя подкаталога, который я получу, но я буду знать имя родительского каталога, поэтому я пытаюсь просто получить имя независимо от того, какой подкаталог находится под ним, и переименуйте его.   -  person newman    schedule 25.02.2021


Ответы (1)


Поскольку вы используете Get-ChildItem без ограничения результата к файлам (через переключатель -File), среди элементов вывода могут быть как файлы, так и каталоги.

В то время как Rename-Item приводит к тихому отказу -op, если файл переименовывается в то же имя, что и в настоящее время, попытка сделать то же самое в каталоге приводит к ошибка, которую вы видели.

Это относится ко всем элементам, имя которых не содержит подстроку 'test', и в этом случае
-replace< /a> операция пропускает входную строку как есть.

Если вы хотите переименовать только файлы, можно просто добавить переключатель -File:

Get-ChildItem -File "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { $_.Name -replace 'test' } 

Если каталоги (также) являются целевыми, как в вашем случае, вам необходимо явно отфильтровать входные элементы, для которых фактическое переименование не произойдет:

Get-ChildItem -Directory -Filter *test* "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { $_.Name -replace 'test' } 

-Filter *test* гарантирует, что выводятся только подкаталоги, содержащие слово 'test', что гарантирует фактическое переименование (хотя обратите внимание, что команда завершится ошибкой, если полное имя подкаталога будет 'test', так как это приведет к возврату блока скрипта пустая строка).


Если вы просто хотите переименовать одиночный подкаталог в фиксированное новое имя, вам вообще не нужен блок скрипта с отложенной привязкой:

# NOTE: Works only if only a SINGLE subdirectory is returned.
Get-ChildItem -Directory "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName 'test'

Если у вас есть несколько подкаталогов и вы хотите включить порядковый номер в новые имена, вам снова понадобится блок скрипта с отложенной привязкой:

$num = 0
Get-ChildItem -Directory "C:\Users\Admin\Desktop\mydirectory\subdirectory" |
  Rename-Item -NewName { 'test' + ++(Get-Variable -Scope 1 num).Value } -WhatIf

Это переименовывает подкаталоги в test1, test2, ...
Для объяснения этого метода (необходимость
Get-Variable), см. этот ответ.


Если вы хотите предварительно просмотреть операции переименования, которые будут выполняться, вы можете добавить -WhatIf общий параметр для вызова Rename-Item, который покажет для каждого входного файла, что он будет переименован в.

Однако вы должны выводить из выходных данных случаи, когда фактическое переименование не происходит из-за блок сценария отложенной привязки, переданный -NewName, возвращает то же имя, что и раньше.

Например, входной файл с именем foo не будет не переименован, потому что 'foo' -replace 'test' возвращает 'foo' без изменений, что с -WhatIf будет отображаться следующим образом (разрывы строк добавлены для удобства чтения) — обратите внимание, как цель и путь назначения являются такой же:

What if: Performing the operation "Rename File" on target "
Item: C:\path\to\foo 
Destination: C:\path\to\foo
"
person mklement0    schedule 24.02.2021
comment
Ваше последнее обновление сработало! Мне нужно было -Directory, а не -File. Спасибо за разъяснение команд фильтра. Это очень краткий ответ, и я определенно чему-то научился. Спасибо еще раз! - person newman; 25.02.2021