Ошибка PowerShell при переименовании вложенных папок

#powershell #rename #subdirectory

#powershell #переименовать #подкаталог

Вопрос:

Я новичок в PowerShell. У меня есть следующая команда для переименования всех вложенных папок:

 Get-ChildItem -r | foreach{Rename-Item $_.FullName ($_.Name -replace "2021", "2021 renamed")}
 

Эта команда работает правильно, но также возвращает сообщение об ошибке:

 Rename-Item : Source and destination path must be different.
At line:1 char:28
  ... e | foreach{Rename-Item $_.FullName ($_.Name -replace "2021", "2021 r ...
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : WriteError: (C:Usersabc...defghi2025:String) [Rename-Item], IOException
      FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
 

Где ...defghi2025 находится последняя вложенная папка.

Может кто-нибудь, пожалуйста, посоветуйте мне, в чем ошибка в моей команде?

Ответ №1:

Если вы хотите переименовывать только вложенные папки, вам следует добавить -Directory параметр. Кроме того, вы можете передавать данные напрямую Rename-Item , цикл foreach не требуется. Сообщение об ошибке отображается для тех элементов, которые вы на самом деле не изменяете (например, в имени нет 2021, поэтому новое имя совпадает со старым.) Вы могли бы просто настроить erroraction на молчаливое продолжение.

 Get-ChildItem -Directory -Recurse |
    Rename-Item -NewName {$_.Name -replace "2021", "2021 renamed"} -ErrorAction SilentlyContinue
 

Или, если вы предпочитаете, вы можете придерживаться цикла и пытаться переименовать только те, которые действительно имеют соответствующие критерии

 Get-ChildItem -r | ForEach-Object{
    if($_.name -match '2021')
    {
        Rename-Item $_.FullName ($_.Name -replace "2021", "2021 renamed")
    }
}
 

Комментарии:

1. Большое спасибо @Doug Maurer — четко объяснил, так что теперь я могу перестать преследовать свой хвост!

2. Однако есть проблема с итерацией файлов / папок и переименованием их в конвейере сразу.. Get-ChildItem может забрать элементы, которые уже были переименованы, и чтобы преодолеть это, вы должны разрешить Get-ChildItem завершить, прежде чем переходить к Rename-Item, заключив его в квадратные скобки: (Get-ChildItem -Directory -Recurse) | Rename-Item .. Кроме того, почему бы не использовать -Filter '*2021*' для получения только папок, в названии которых есть 2021?