Массовое переименование файлов в powershell и добавление количества к каждому имени файла

#powershell #count #rename #bulk

#powershell #количество #переименовать #массовое

Вопрос:

Я могу массово переименовывать файлы в каталоге ИЛИ заменять каждое имя файла количеством, однако мне нужно, чтобы оба были объединены.

Массовое переименование (сохраните первые 2 символа исходного имени):

 Get-ChildItem * |  
    Rename-Item -NewName { $_.BaseName.Split('-')[0]   $_.Extension }
  

(частично жестко запрограммированное решение, я знаю!)

В качестве альтернативы, добавьте количество:

 $count = 1
Get-ChildItem * | % { Rename-Item $_ -NewName (‘{0}.xlsx’ -f $count  ) }
  

(Я даже не мечтаю о завершающих 0s)

Я пытался объединить обе вещи, но безрезультатно. Что я делаю не так?

Моя неудачная попытка:

 $count = 1 
Get-ChildItem * |
    Rename-Item -NewName { $_.BaseName.Split('-')[0] -f $count     $_.Extension }
  

Ответ №1:

Вы неправильно понимаете, как работает оператор format. Вам нужна строка формата с заполнителем ( {0} ), чтобы заставить этот оператор работать. Я бы также рекомендовал заключить группирующие скобки вокруг этого выражения, хотя в данном случае это не требуется. На всякий случай.

 ('foo {0} bar' -f $some_var)   $other_var
  

С учетом сказанного, вы, очевидно, хотите добавить значение переменной counter к фрагменту из исходного имени файла, а не использовать этот фрагмент в качестве строки формата. Для этого вы можете просто объединить счетчик с фрагментом, как вы делаете с расширением.

Для корректной работы счетчика вам также необходимо указать правильную область. Способ, которым вы его используете, определяет новую переменную $counter в локальной области scriptblock каждый раз при переименовании файла, поэтому переменная $counter в родительской области никогда не увеличивается. Используйте модификатор script: or global: scope, чтобы получить переменную, которую вы действительно собираетесь использовать.

 $count = 1
Get-ChildItem * |
    Rename-Item -NewName { $_.BaseName.Split('-')[0]   $script:count     $_.Extension }
  

Если вы хотите использовать оператор format вместо конкатенации строк ( ), вы должны использовать его следующим образом:

 $count = 1
Get-ChildItem * |
    Rename-Item -NewName { '{0}{1}{2}' -f $_.BaseName.Split('-')[0], $script:count  , $_.Extension }
  

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

1. Ansgar, переименование работает, но я заметил, что оно также добавляет количество к вложенным папкам текущего каталога. Как я могу указать, что я хочу, чтобы учитывались только определенные расширения файлов или, в качестве альтернативы, только файлы внутри данного каталога (без вложенных папок).

2. @monechka Вы можете использовать Where-Object фильтр для ограничения Get-ChildItem результатов. Get-ChildItem также имеет некоторые параметры, которые позволяют различать, что должен возвращать командлет.

Ответ №2:

Чтобы подсчитать количество $count, вам нужно выполнить цикл.

 $count = 1 
Get-ChildItem * | foreach-object { Rename-Item -NewName { $_.BaseName.Split('-')[0] -f 
 count     $_.Extension } }
  

% — это псевдоним командлета foreach-object, который вы использовали в подходе «добавить количество».
Просто добавил его к неудачной попытке.

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

1. Теперь я получаю эту ошибку: В строке: 2 char:87 … -object { Переименовать-Item -NewName { $_.BaseName . Split(‘-‘)[0] -f count … ~ Необходимо указать выражение значения после оператора ‘-f’.

2. В строке: 2 символа: 88 … { Rename-Item -NewName { $_.BaseName. Split(‘-‘)[0] -f count $_.Ex … ~~~~~~~ Неожиданный токен «count » в выражении или операторе. CategoryInfo: ParserError: (:) [], ParentContainsErrorRecordException FullyQualifiedErrorId: ожидаемое значение выражения

3. извините, пришлось разделить, комментарий был слишком длинным

4. Ваше утверждение не только фактически неверно (вы можете абсолютно увеличить счетчик в scriptblock, используемом с Rename-Item ), но и код в вашем ответе еще более нарушен, чем в вопросе.