Как рекурсивно переименовывать файлы в каталоге с помощью Powershell?

#powershell

Вопрос:

У меня есть скрипт powershell, который добавляет «- Конфиденциально» в конец файлов, которые еще не соответствуют строке «Конфиденциально» в имени файла. При запуске этого скрипта в каталоге он работает. Однако мне нужно, чтобы он также переименовал все элементы в подпапке. Как я мог этого достичь?

     Get-ChildItem * -Exclude *Confidential* -Recurse | 
  ForEach {Rename-Item -NewName { $_.BaseName   " - Confidential"   $_.Extension }}
 

Спасибо всем за чтение.

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

1. Вам нужно указать путь: Rename-Item -Path $_.FullName -NewName { $_.BaseName " - Confidential"...

2. @AbrahamZinala Извините, не могли бы вы уточнить, пожалуйста? Нужно ли мне указывать путь или просто добавить параметр-Path?

3. @AbrahamZinala Добавление пути, похоже, не помогает.

4. Предложение @AbrahamZinala должно сработать. Вы вошли -Path $_.FullName , как он предложил? Вы также можете удалить ForEach канал и напрямую Rename-Item , и в этом случае вы можете опустить путь. Get-ChildItem * -Exclude *Confidential* -Recurse | Rename-Item -NewName { $_.BaseName ' - Confidential' $_.Extension }

Ответ №1:

Вы близки, но есть несколько проблем:

  1. Rename-Item отсутствует исходный файл, поэтому давайте добавим $_ к нему. Мы могли бы также дать его $_.FullName , но я просто передаю ему весь объект целиком.
  2. Rename-Item дается блок сценария без ввода -NewName , потому что вы использовали фигурные скобки ( {} ), поэтому мы меняем его на обычные скобки ( () ).
  3. Вложенные папки также переименовываются, что также приводит к тому, что файлы в них не рекурсируются (потому что они содержат конфиденциальные данные), поэтому мы указываем -File переключатель вкл Get-ChildItem .только для возвращаемых файлов.

Итак, это подводит нас к следующему:

 Get-ChildItem * -File -Exclude *Confidential* -Recurse | 
  ForEach {Rename-Item $_ -NewName ( $_.BaseName   " - Confidential"   $_.Extension )}
 

И просто немного очистки/оптимизации:

  1. Удалите подстановочный знак ( * ) из Get-ChildItem . Он уже предполагает все элементы в папке, в которой вы находитесь.
  2. Заключите строку в кавычки.
  3. Добавьте несколько пробелов внутри блока сценария и измените ForEach псевдоним на более короткий % псевдоним (оба только по моему личному предпочтению).

И конечный результат выглядит так:

 Get-ChildItem -File -Exclude "*Confidential*" -Recurse | 
  % { Rename-Item $_ -NewName ( $_.BaseName   " - Confidential"   $_.Extension ) }
 

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

Правка: На самом деле вы могли бы просто передать вывод Get-ChildItem в Rename-Item , как таковой, без необходимости ForEach-Object :

 Get-ChildItem -File -Exclude "*Confidential*" -Recurse | 
  Rename-Item -NewName { $_.BaseName   " - Confidential"   $_.Extension }