Simple Script for renumbering on file names

I know this is likely an easy question to answer, but i don’t script often and have coming up against a wall.
I’m hoping someone can have sympathy on me. haha.

I have almost 200 files which I named in the opposite order to what I wanted in number.
The Naming scheme is:
001 .
002 .
… 196 .

Thus I want to simply create a script which reads each filename and then renames each number in the filename 197-(number).

I’m trying to use powershell, but perl or python would be fine. (I haven’t used perl or python in years, but it should be easy enough to follow along.)

I can think of multiple ways to approach this, but every simple direction seems to have a problem I can’t get past. For example., I can’t do the simple math in the renaming.
The closest I’ve been able to get to solving this stupidly simple problem is the following:

$N=1
Dir | %{Rename-Item $_ -NewName ({0} + string.substring(4) -f $N++)}

OR

Dir | %{Rename-Item $_ -NewName (’{0}’ + string.substring(4) -f $N++)}

but both fail on multiple levels, and this should be really easy!
{0} + – works, but returns not the variable, but {0} in the filename;
‘{0}’ + – fails, probably because of some issue between strings and arithmetical operations.

Maybe I’m approaching it wrong, but I’m just not someone who does scripting much and haven’t programmed in 30yrs. I’m basically wanting something like:

N=1;
for N 1 to 196 do
replace (^/d{3}) with (197-N)+C {to avoid a potential infinite loop} in the filenames; N++

Thank you in advance if you’re able to help.

For readability, put your code in [ code]Your Code here[/code ] (minus the spaces in the square brackets.

Never used PowerShell beyond “Do this with x parameter, then that with…”

1 Like

I’m sure someone here than can create you a powershell script, but if it’s a one-off task why bother scripting it out? I spent less than 5 minutes creating this batch using regex but you could probably had renamed the files manually in the same amount of time.

Just use find/replace to fill in your filenames

Batch file
ren [filename]001.[ext] [filename]197.tmp
ren [filename]002.[ext] [filename]196.tmp
ren [filename]003.[ext] [filename]195.tmp
ren [filename]004.[ext] [filename]194.tmp
ren [filename]005.[ext] [filename]193.tmp
ren [filename]006.[ext] [filename]192.tmp
ren [filename]007.[ext] [filename]191.tmp
ren [filename]008.[ext] [filename]190.tmp
ren [filename]009.[ext] [filename]189.tmp
ren [filename]010.[ext] [filename]188.tmp
ren [filename]011.[ext] [filename]187.tmp
ren [filename]012.[ext] [filename]186.tmp
ren [filename]013.[ext] [filename]185.tmp
ren [filename]014.[ext] [filename]184.tmp
ren [filename]015.[ext] [filename]183.tmp
ren [filename]016.[ext] [filename]182.tmp
ren [filename]017.[ext] [filename]181.tmp
ren [filename]018.[ext] [filename]180.tmp
ren [filename]019.[ext] [filename]179.tmp
ren [filename]020.[ext] [filename]178.tmp
ren [filename]021.[ext] [filename]177.tmp
ren [filename]022.[ext] [filename]176.tmp
ren [filename]023.[ext] [filename]175.tmp
ren [filename]024.[ext] [filename]174.tmp
ren [filename]025.[ext] [filename]173.tmp
ren [filename]026.[ext] [filename]172.tmp
ren [filename]027.[ext] [filename]171.tmp
ren [filename]028.[ext] [filename]170.tmp
ren [filename]029.[ext] [filename]169.tmp
ren [filename]030.[ext] [filename]168.tmp
ren [filename]031.[ext] [filename]167.tmp
ren [filename]032.[ext] [filename]166.tmp
ren [filename]033.[ext] [filename]165.tmp
ren [filename]034.[ext] [filename]164.tmp
ren [filename]035.[ext] [filename]163.tmp
ren [filename]036.[ext] [filename]162.tmp
ren [filename]037.[ext] [filename]161.tmp
ren [filename]038.[ext] [filename]160.tmp
ren [filename]039.[ext] [filename]159.tmp
ren [filename]040.[ext] [filename]158.tmp
ren [filename]041.[ext] [filename]157.tmp
ren [filename]042.[ext] [filename]156.tmp
ren [filename]043.[ext] [filename]155.tmp
ren [filename]044.[ext] [filename]154.tmp
ren [filename]045.[ext] [filename]153.tmp
ren [filename]046.[ext] [filename]152.tmp
ren [filename]047.[ext] [filename]151.tmp
ren [filename]048.[ext] [filename]150.tmp
ren [filename]049.[ext] [filename]149.tmp
ren [filename]050.[ext] [filename]148.tmp
ren [filename]051.[ext] [filename]147.tmp
ren [filename]052.[ext] [filename]146.tmp
ren [filename]053.[ext] [filename]145.tmp
ren [filename]054.[ext] [filename]144.tmp
ren [filename]055.[ext] [filename]143.tmp
ren [filename]056.[ext] [filename]142.tmp
ren [filename]057.[ext] [filename]141.tmp
ren [filename]058.[ext] [filename]140.tmp
ren [filename]059.[ext] [filename]139.tmp
ren [filename]060.[ext] [filename]138.tmp
ren [filename]061.[ext] [filename]137.tmp
ren [filename]062.[ext] [filename]136.tmp
ren [filename]063.[ext] [filename]135.tmp
ren [filename]064.[ext] [filename]134.tmp
ren [filename]065.[ext] [filename]133.tmp
ren [filename]066.[ext] [filename]132.tmp
ren [filename]067.[ext] [filename]131.tmp
ren [filename]068.[ext] [filename]130.tmp
ren [filename]069.[ext] [filename]129.tmp
ren [filename]070.[ext] [filename]128.tmp
ren [filename]071.[ext] [filename]127.tmp
ren [filename]072.[ext] [filename]126.tmp
ren [filename]073.[ext] [filename]125.tmp
ren [filename]074.[ext] [filename]124.tmp
ren [filename]075.[ext] [filename]123.tmp
ren [filename]076.[ext] [filename]122.tmp
ren [filename]077.[ext] [filename]121.tmp
ren [filename]078.[ext] [filename]120.tmp
ren [filename]079.[ext] [filename]119.tmp
ren [filename]080.[ext] [filename]118.tmp
ren [filename]081.[ext] [filename]117.tmp
ren [filename]082.[ext] [filename]116.tmp
ren [filename]083.[ext] [filename]115.tmp
ren [filename]084.[ext] [filename]114.tmp
ren [filename]085.[ext] [filename]113.tmp
ren [filename]086.[ext] [filename]112.tmp
ren [filename]087.[ext] [filename]111.tmp
ren [filename]088.[ext] [filename]110.tmp
ren [filename]089.[ext] [filename]109.tmp
ren [filename]090.[ext] [filename]108.tmp
ren [filename]091.[ext] [filename]107.tmp
ren [filename]092.[ext] [filename]106.tmp
ren [filename]093.[ext] [filename]105.tmp
ren [filename]094.[ext] [filename]104.tmp
ren [filename]095.[ext] [filename]103.tmp
ren [filename]096.[ext] [filename]102.tmp
ren [filename]097.[ext] [filename]101.tmp
ren [filename]098.[ext] [filename]100.tmp
ren [filename]099.[ext] [filename]099.tmp
ren [filename]100.[ext] [filename]098.tmp
ren [filename]101.[ext] [filename]097.tmp
ren [filename]102.[ext] [filename]096.tmp
ren [filename]103.[ext] [filename]095.tmp
ren [filename]104.[ext] [filename]094.tmp
ren [filename]105.[ext] [filename]093.tmp
ren [filename]106.[ext] [filename]092.tmp
ren [filename]107.[ext] [filename]091.tmp
ren [filename]108.[ext] [filename]090.tmp
ren [filename]109.[ext] [filename]089.tmp
ren [filename]110.[ext] [filename]088.tmp
ren [filename]111.[ext] [filename]087.tmp
ren [filename]112.[ext] [filename]086.tmp
ren [filename]113.[ext] [filename]085.tmp
ren [filename]114.[ext] [filename]084.tmp
ren [filename]115.[ext] [filename]083.tmp
ren [filename]116.[ext] [filename]082.tmp
ren [filename]117.[ext] [filename]081.tmp
ren [filename]118.[ext] [filename]080.tmp
ren [filename]119.[ext] [filename]079.tmp
ren [filename]120.[ext] [filename]078.tmp
ren [filename]121.[ext] [filename]077.tmp
ren [filename]122.[ext] [filename]076.tmp
ren [filename]123.[ext] [filename]075.tmp
ren [filename]124.[ext] [filename]074.tmp
ren [filename]125.[ext] [filename]073.tmp
ren [filename]126.[ext] [filename]072.tmp
ren [filename]127.[ext] [filename]071.tmp
ren [filename]128.[ext] [filename]070.tmp
ren [filename]129.[ext] [filename]069.tmp
ren [filename]130.[ext] [filename]068.tmp
ren [filename]131.[ext] [filename]067.tmp
ren [filename]132.[ext] [filename]066.tmp
ren [filename]133.[ext] [filename]065.tmp
ren [filename]134.[ext] [filename]064.tmp
ren [filename]135.[ext] [filename]063.tmp
ren [filename]136.[ext] [filename]062.tmp
ren [filename]137.[ext] [filename]061.tmp
ren [filename]138.[ext] [filename]060.tmp
ren [filename]139.[ext] [filename]059.tmp
ren [filename]140.[ext] [filename]058.tmp
ren [filename]141.[ext] [filename]057.tmp
ren [filename]142.[ext] [filename]056.tmp
ren [filename]143.[ext] [filename]055.tmp
ren [filename]144.[ext] [filename]054.tmp
ren [filename]145.[ext] [filename]053.tmp
ren [filename]146.[ext] [filename]052.tmp
ren [filename]147.[ext] [filename]051.tmp
ren [filename]148.[ext] [filename]050.tmp
ren [filename]149.[ext] [filename]049.tmp
ren [filename]150.[ext] [filename]048.tmp
ren [filename]151.[ext] [filename]047.tmp
ren [filename]152.[ext] [filename]046.tmp
ren [filename]153.[ext] [filename]045.tmp
ren [filename]154.[ext] [filename]044.tmp
ren [filename]155.[ext] [filename]043.tmp
ren [filename]156.[ext] [filename]042.tmp
ren [filename]157.[ext] [filename]041.tmp
ren [filename]158.[ext] [filename]040.tmp
ren [filename]159.[ext] [filename]039.tmp
ren [filename]160.[ext] [filename]038.tmp
ren [filename]161.[ext] [filename]037.tmp
ren [filename]162.[ext] [filename]036.tmp
ren [filename]163.[ext] [filename]035.tmp
ren [filename]164.[ext] [filename]034.tmp
ren [filename]165.[ext] [filename]033.tmp
ren [filename]166.[ext] [filename]032.tmp
ren [filename]167.[ext] [filename]031.tmp
ren [filename]168.[ext] [filename]030.tmp
ren [filename]169.[ext] [filename]029.tmp
ren [filename]170.[ext] [filename]028.tmp
ren [filename]171.[ext] [filename]027.tmp
ren [filename]172.[ext] [filename]026.tmp
ren [filename]173.[ext] [filename]025.tmp
ren [filename]174.[ext] [filename]024.tmp
ren [filename]175.[ext] [filename]023.tmp
ren [filename]176.[ext] [filename]022.tmp
ren [filename]177.[ext] [filename]021.tmp
ren [filename]178.[ext] [filename]020.tmp
ren [filename]179.[ext] [filename]019.tmp
ren [filename]180.[ext] [filename]018.tmp
ren [filename]181.[ext] [filename]017.tmp
ren [filename]182.[ext] [filename]016.tmp
ren [filename]183.[ext] [filename]015.tmp
ren [filename]184.[ext] [filename]014.tmp
ren [filename]185.[ext] [filename]013.tmp
ren [filename]186.[ext] [filename]012.tmp
ren [filename]187.[ext] [filename]011.tmp
ren [filename]188.[ext] [filename]010.tmp
ren [filename]189.[ext] [filename]009.tmp
ren [filename]190.[ext] [filename]008.tmp
ren [filename]191.[ext] [filename]007.tmp
ren [filename]192.[ext] [filename]006.tmp
ren [filename]193.[ext] [filename]005.tmp
ren [filename]194.[ext] [filename]004.tmp
ren [filename]195.[ext] [filename]003.tmp
ren [filename]196.[ext] [filename]002.tmp
ren [filename]197.[ext] [filename]001.tmp
ren *.tmp *.[ext]
2 Likes

IMO this type of task, with up to hundreds of thousands of files, is less fraught and more reliably done by first generating a file of rename commands. One can use whatever programming, text editing or scripting skills are to hand. Then, one can check the list before potentially destroying the files, and possibly patch up corner cases.
Using code that calculates the new names while renaming is difficult to test, and a mistake means loss of files.
In your case I think you need to do two passes to avoid collisions. If you first rename 001 to 196 what happens to file 196?

That is definitely a problem, but in powershell one has some options.
for example, at the end of the command, you can add the flag -whatif which shows what your code does without making changes. that said, -whatif doesn’t always catch all errors, and I think this renaming error is not caught by -whatif.
Another aspect of how one can approach these issues it is to also change the extension, as @Four0Four 's batch file had as an example. It was a good suggestion which just hadn’t occurred to me as a good safe guard methodology.

Lastly, for something like this, I copy a small number of files in a test folder and hit them with scripts. Currently, various problems are showing up.

One direction I’m trying now is using an ARRAY and a FOR loop.
In Powershell, setting up a contextually appropriate ARRAY is easy: literally, $VAR=196…1
This has the advantage of being indexed exactly the way I want, where
$VAR[1] = 196 and $VAR[196] = 1 .

So I figured a FOR loop could make this easy, but everything I try is having some kind of issue with this ARRAY element.
Sadly, as I already wrote, I don’t have a head for code. It’s not obvious to me when I’m calling an ARRAY element or or sometimes the entire ARRAY or making it literal text, and sometimes none of these three above work properly in the code I write.

I’d love to figure this out, because I prefer to learn how to think better about a problem rather than hitting bluntly, but i dunno… haha. I’ve tried working on this stupid problem several times over the past few months, but with little success. So I posted it here, on Level1Tech, because I really like watching “The Dream Team” on YouTube.

Anyway, it’s fine if I have to solve this is barbaric way, I’m just hoping to understand better.
Thank you.

If you are not looking for the learning experience, and just want the rename done. . . .I would recommend checking out the “PowerRename” app that is a part of the PowerToys suite. The app may meet your needs.

1 Like

I decided to take a stab at this in PowerShell. I think I understand what you are trying to do so here is my attempt.

I used “Copy-Item” rather than Rename-Item" to avoid destroying files and filename already existing errors. You might be able to switch the command. If you do switch I would recommend testing, test again, and test more before using on valued files!

You will need to replace variables to match your scenario.

Disclaimer: YMMV, no warranty, be CAREFUL! This is a script on the internet! :wink:

<#
YMMV
This script could be destructive and does not handle all exceptions!  No warranty!

This script will invert the file numbers of the assumed {filename}{000}.{ext}
#>

#Place your max file number in this variable
[int]$maxFileNumber = "195"

#Place your new file name in this variable
$newfileName = "copyTest"

#Place your file extension here
$fileExt = "txt"

#Place your core file name here:
$currentFileName = "testing"

#Retrieves all files that match the -Path expression in the current directory
$fileList = ((Get-ChildItem -Path .\$currentFileName*).Name)


foreach ($file in $fileList) {

    #Extracts the file number from the $file variable
    $fileNumberOld = ($file -replace '[^0-9]')

    #Creates the new file number by subtracting the $fileNumberOld from the $maxFileNumber
    $fileNumberNew = ($maxFileNumber-([int]$fileNumberOld))

    #Copys the old $file and with the new file name
    Copy-Item -Path $file -Destination ($newfileName + ($fileNumberNew.ToString("000")) + ".$fileExt")
    

}

EDITED for cleaner code block

1 Like

Using the script above:

“testing001.txt” becomes “copyTest194.txt”
. . .
“testing100.txt” becomes “copyTest095.txt”
. . .
“testing194.txt” becomes “copyTest001.txt”

Another idea to mod the script.

Delete the following

#Place your max file number in this variable
[int]$maxFileNumber = "195"

After the $fileList variable is created add the following:

#determines the max file/number in the array
$maxFileName = ($fileList | Measure-Object -Maximum)

#Extracts the max file number from the "Maximum" field in $maxFileName
[int]$maxFileNumber = ($maxFileName.Maximum -replace '[^0-9]')

#Increments the max file number by 1 to remove 0 only filename
$maxFileNumber++

1 Like

I wanted to thank you for taking the time to write this code. I got busy so I haven’t had a chance to try it yet - probably tomorrow or the next day; but the code looks good and it’s easy to follow.
And just to reconfirm what you wrote. I understand I’m using it at my own risk. no problem.

My actual files are named with the numbers first and then the titles instead of just before the , but I don’t foresee a real problem changing the code.
There might be another place to change the code slightly, but at least one place seems an obvious change:

Copy-Item -Path $file -Destination (($fileNumberNew.ToString("000") + $newfileName) + ".$fileExt")
 
<code>
1 Like

If I could just ask one question:
Does this line of yours just replace all non-digits with nothing/null?

#Extracts the file number from the $file variable $fileNumberOld = ($file -replace '[^0-9]')

I ask because I thought one always needed to indicate what will be the replacement. I just never thought of approaching it this way.

One tip I’ll give - if this is a one off type thing you just want to get done - don’t overlook exporting into excel via export csv, creating some more columns and importing back into powershell then just iterating through a loop.

Couple of one-two liners without getting fancy with regex etc.

Elegant? No but reusable yes and dumb as rocks simple to do vs trying to script it fully.

If all you need to do is get it done in a hurry… don’t over engineer it.

I’d probably do something like this in bash:

for x in {001..200}; do
  mv -n -v \
    "file${x}.txt" \
    "file$(printf "%03d" $((200 - 10#${x} + 1))).txt"
done
  • {a..b} will generate a range
  • $(printf ...) will a command and puts the value inline into the command.
  • printf "%03d" ... is a builtin bash command to format numbers with three digits, using leading zeros as needed.
  • $((1 + 1)) is a builtin to do maths (who needs bc).
  • 10#$x is a way of specifying that a string should be interpreted as a base-10 number. Normally you don’t need this, but we’re dealing with leading zeros that bash interprets as octal - so “010” would become 8.
$ echo $(("010"))
8

You can also use bash parameter expansion to rename file types. Something like this - ${x%%.txt} - will remove the file extension of filenames (Yes bash has regex support). The “Parameter Expansion” section of the bash man page will show you what else is possible here.

1 Like

as I suggested, whatever skills are to hand

Thanks!
It worked great with very minor adjustments.

I’ll post the code I used in the (unlikely) event someone is looking for a powershell script to invert numbers on files with a naming scheme Title.

<# YMMV This script could be destructive and does not handle all exceptions! No warranty!

This script will invert the file numbers of the assumed {000}{filename}.{ext}
by creating a copy of each inverted file with a .tmp extension.
#>

#Place your file extension here
$fileExt = “”

#Retrieves all files that match the -Path expression in the current directory
$fileList = ((Get-ChildItem .*.$fileExt).Name)

#determines the number of files in the array
[int]$maxFileNumber = $fileList.count

#Increments the max file number by 1 to remove 0 only filename
$maxFileNumber++

foreach ($file in $fileList) {

#Extracts the file number from the $file variable
$fileNumberOld = $file.substring(0,3)

#Creates the new file number by subtracting the $fileNumberOld from the $maxFileNumber
$fileNumberNew = ($maxFileNumber-([int]$fileNumberOld))


#Copys the old $file and with the new file name
Copy-Item $file (($fileNumberNew.ToString("000")) + " " + $file.substring(3) + ".tmp")

}

1 Like

That’s very cool and to some extent the kind of code I was hoping to use.

I haven’t used bash since dinosaurs were still around, lol, but there’s an elegance to it and to perl that I like, but I just haven’t had the time to really get back into these scripting forms.
I’m just curious though, wouldn’t there be the possibility of collisions with this script?
I find some of my recent powershell scripts seem fine, but, when I use them, they end up redoing the same file a second time.
Anyway, thanks for providing a different approach to the problem. I plan to look this over later.

Good catch, for this reason it’s often useful to put the processed files into another directory. Or to use a prefix or postfix on the new files. (Also good practise to use some kind of non-overwrite option on the move, like “-n” on mv).

Correct.

I don’t recall exactly how I found the -replace with no substitution offered isolates the data. I think I started with trying to use Select-String but was not getting the results I wanted and stumbled into -replace.

I did reference these two pages (among many others) when making the script. Definitely a lot of trial and error.

Docs on -replace

Docs on regex