Команда 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 0s, что-либо выше или ниже будет 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 }
Другие вопросы по тегам