Команда PowerShell для последовательного переименования файлов
Я пытаюсь облегчить именование пакетных файлов для моих конечных пользователей. При фотографировании наших местоположений мы можем иногда иметь только 1 фотографию или 500 в зависимости от размера местоположения. Приведенный ниже код прекрасно работает для массового переименования наших фотографий в зависимости от количества файлов в каталоге:
$prefix = "[SomePrefix]"
$files = Get-ChildItem
$id = 1
$files | foreach { Rename-Item -Path $_.fullname -NewName ( $prefix + ((($id++).tostring()).padleft(($files.count.tostring()).length) -replace ' ','0' ) + $_.extension) }
Код дополняет имя файла фотографии начальными нулями в зависимости от количества файлов в каталоге, то есть 1, 2, 3, 4, 5, если общее количество файлов меньше 9; 01, 02, 03, 04, 05, если общее количество файлов составляет от 10 до 99; 001, 002, 003, 004, 005, если общее количество файлов составляет от 100 до 999.
Мне нужно изменить этот код так, чтобы он ВСЕГДА сохранял 3 ведущих нуля 001, 002, 003, 004, 005 независимо от количества файлов в каталоге. Тем не менее, мне нужен код для повторного просмотра в существующем каталоге, чтобы я мог избавить пользователей от необходимости организовывать свои фотографии в разные папки на основе номера (0-9; 10-99; 100-999) и запускать отдельные строки кодов для каждый.
Пример соглашения об именах файлов фотографий: PREFIX_001.jpg
Может кто-нибудь сказать мне, как изменить вышеуказанный код в соответствии с моими потребностями?
3 ответа
PadLeft
здесь не нужно
.ToString("000")
приведет к добавлению номера к 3 цифрам.
см. страницу о форматировании чисел для более подробной информации здесь
Вы можете настроить свой код так, чтобы он всегда дополнял минимально необходимое количество цифр, выполнив это:
$Prefix = "[SomePrefix]"
$Files = Get-ChildItem
$PadTo = '0'*$Files.Count.ToString().Length
$ID = 1
$Files | ForEach { Rename-Item -LiteralPath $_.fullname -NewName ($prefix + ($id++).tostring($PadTo) + $_.extension) }
это создает строку $PadTo
который просто ряд 0
в зависимости от того, сколько файлов в вашем каталоге, если у вас есть 100-999
файлов будет 3 0
s, что-либо выше или ниже будет 4,5 и т. д., чтобы соответствовать.
Я бы порекомендовал быть осторожным с квадратными скобками, так как это можно интерпретировать как нечто вроде группового символа.
$Prefix = '[SomePrefix]'
$Path = '.'
$Folders = Get-ChildItem -LiteralPath $Path -Directory -Recurse
ForEach ($Folder in $Folders)
{
$Counter = 0
Get-ChildItem $Folder -File |
ForEach-Object {
Rename-Item $_.FullName -NewName "${Prefix}_$($Counter.ToString('000'))$($_.Extension)"
$Counter++
}
}
Это решение будет рекурсивно переименовывать все файлы в каталогах на основе определения $Path
в Prefix_001.ext
формат
Rename-Item
может принимать входные данные конвейера, поэтому нет необходимости вForEach
зацикливание.
Кроме того, трубопроводFileInfo
объекты командлету, избавляет от необходимости учитывать,-Path
или-LiteralPath
требуется, чтобы избежать ошибок:
$Prefix = '[SomePrefix]'
$PadWidth = ([String](($Files = Get-ChildItem -File -Recurse).Count)).Length
$Format = "${Prefix}_{0:d$PadWidth}{1}"
[ref]$i = 1
$Files | Rename-Item -NewName { $format -f $i.Value++ , $_.Extension }