#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
), но и код в вашем ответе еще более нарушен, чем в вопросе.