I've got a bunch of files named as:
01. Filename.ext
02. Filename.ext
03. Filename.ext
etc.I need to batch rename them with PowerToys PowerRename by increasing the number in the beginning of the file name by a specific value, say 15, so that their names become, for example:
16. Filename.ext
17. Filename.ext
18. Filename.ext
etc.As far as I understand I should use Regular Expressions for this task. Unfortunately it is all I understand regarding this matter.
So I'm asking your help with this exact task: what to put into the "Search for:" and "Replace with:" fields?
03 Answers
PowerRename is not the right tool for this type of complex rename. A more powerful tool isBulk Rename Utility, free for personal use.
For example, I combine below the operations of:
- Remove the first two characters
- Prepend an incrementing number starting from 16
The PowerShell option:
$Increment = 15
Get-ChildItem | Where Name -match '^(\d+)(.+)$' | Select FullName, @{ N = 'Index' ; E = { [Int]$Matches[1] }}, @{ N = 'NameText' ; E = { $Matches[2] }} |
Sort Index -Descending | ForEach{ Rename-Item $_.FullName -NewName ( '{0:d2}{1}' -f ( $_.Index + $Increment ), $_.NameText ) }Breaking it down:
- The
-matchoperator uses regular expression matching, returns a boolean value & populates the$MatchesAutomatic Variable. The regular expression'^(\d+)(.+)$'will match any string beginning with one or more digits and at least one character following those digits and generate two capture groups, the leading digits in the first and all subsequent text in the second:
PS C:\>>'01. FileName.txt' -match '^(\d+)(.+)$'
True
PS C:\> $matches
Name Value
---- -----
2 . FileName.txt
1 01
0 01. FileName.txt- The
-fFormat operator constructs a string using a template and a list of values/varibles. Format specifiers like thed2in{0:d2}can add leading zeros among other things:
PS C:\>'{0:d2}{1}' -f 7, '. FileNaem.txt'
07. FileNaem.txt- The Rename-Item Cmdlet's
-NewNameparameter can be either a string or a scriptblock, the scriptblock allowing the new name to be based on the values in the current$Matchesvariable:
{ '{0:d2}{1}' -f ( $Increment + $matches[1] ), $matches[2] } 5 // Edit
Inspired by @Keith Miller's idea of using a descending/reverse loop to rename files in cmd/bat:
set "_n=" & set "_c=" & <nul (for /l %i in (99 -1 16)do set/a "_c=100%~i-15, _n=100%~i" && cmd/v/c "ren "!_c:~-2!.*.ext" "!_n:~-2!.*.ext"")To do the same in PowerShell:
$i=(ls *.ext).count+16 ; For($i -eq 15; $i--) { $old=($i-15).ToString("00") ; ls $($old+'. *.ext')| % {ren $_ -new ($_.Name.Replace("$old. ","$i. "))}} Edit //
set "_n=" & for /l %i in (1 1 84)do @set "_n=00%~i" && @cmd/v/c "ren "!_n:~-2!.*.ext" "!_n:~-3!.*.ext""
set "_n=" & set "_c=" & >nul (for /l %i in (1 1 84)do @set/a "_c=1000%~i+15" && @set/a "_n=1000+%~i" && @cmd/v/c "ren "!_n:~-3!.*.ext" "!_c:~-2!.*.ext"")You can do this in command line too:
Obs.:1. Assuming that when renaming two-digit numbers
Obs.:2. Your folder has a total of 84 files = 100 - 16
Obs.:3. All files have the same extension.
1. First, add a digit to each file, renaming 16. file.ext -> 016. file.ext, thus avoiding conflict when renaming 01. file.ext for the name of 16. file.ext (existing file)
set "_n=" & for /l %i in (1 1 84)do @set "_n=00%~i" && @cmd/v/c "ren "!_n:~-2!.*.ext" "!_n:~-3!.*.ext""Obs.:4. Use For /L loop from 1 to 84, define _n=001, when adding 00, in the front variable %i, a substring of maximum length 2 (file source "!_n:~-2!.*.ext") and a substring of maximum length 3 (file target "!_n:~-3!.*.ext") will be used by ren for rename your files in loop:
2. Use again a For /L loop from 1 to 84, define _c=1000%~i+15, when adding 1000, adding to the variable %i, a substring of maximum length 3 (file source "!_c:~-3!.*.ext") and a substring of maximum length 3 (file target "!_n:~-2!.*.ext") will be used by ren for rename your files in loop:
for /l %i in (1 1 84)do @set/a "_c=1000%~i+15" && @set/a "_n=1000+%~i" && @cmd/v/c "ren "!_n:~-3!.*.ext" "!_c:~-2!.*.ext""Obs.:5. The result in the loop will be from 1 to 84:
ren 001.file.ext 16.file.ext
ren 002.file.ext 17.file.ext
ren 003.file.ext 18.file.ext ...
ren 084.file.ext 99.file.extObs.:6. This can easily be expanded to 1 to 840, 1 to 8400, ...:
for /l %i in (1 1 840)do ... ... set "_n=000%~i" ... cmd/v/c "ren "!_n:~-3!.*.ext" "!_n:~-4!.*.ext""
for /l %i in (1 1 840)do ...
... set/a "_c=10000%~i+15"
... set/a "_n=10000+%~i"
... cmd/v/c "ren "!_n:~-4!.*.ext" "!_c:~-3!.*.ext"")The same in Bat/CMD:
@echo off && cd /d "%~dp0"
set "_n=" & for /l %%i in (1 1 84
)do set "_n=00%%~i" && cmd/v/c "ren "!_n:~-2!.*.ext" "!_n:~-3!.*.ext""
set "_n=" & set "_c=" & >nul (for /l %%i in (1 1 84
)do set/a "_c=1000%%~i+15, _n=1000+%%~i" && cmd/v/c "ren "!_n:~-3!.*.ext" "!_c:~-2!.*.ext"")Some further reading:
[√] set /?
[√] Cmd /?
[√] Ren | Rename
[√] For Loop
[√] For /F Loop
[√] Syntax Substring
[√] Understanding start, 2>nul, cmd, and other symbols in a batch file