PowerShell: How To Reverse Alphabetical File Names & Rename

Recently I had shot a bunch of videos on a Video App on my iPhone. By default it saves the videos/photos within the App itself. Later, I can move them to iPhone “Photos”.

Why are file names in reverse order of how I shot them?

In the case of this app, I just did “Select All” within the app and moved all the videos over to “Photos”. When I downloaded the content to my computer, I noticed that it downloaded the most recently downloaded video first and the oldest video last. This meant the file names given to the videos were in reverse order of chronological order.

For example, this is the list of files:

IMG_6246.MOV   <<-- This is the video I shot most recently
IMG_6247.MOV
IMG_6248.MOV
IMG_6249.MOV
IMG_6250.MOV
IMG_6251.MOV
IMG_6252.MOV
IMG_6253.MOV
IMG_6254_Blurry.MOV
IMG_6255.MOV
IMG_6256.MOV
IMG_6257.MOV
IMG_6258.MOV
IMG_6259.MOV
IMG_6260.MOV
IMG_6261.MOV
IMG_6262.MOV   <<-- This is the video I shot first

Refusing to choose easy!

I would have liked the file names to be in the order I shot the videos, however, the app messes it up when I move these files with the “Select All” option. I am sure there is an easy way within the app like sorting it first and then moving. But I refuse to choose easy!

Immediately, I was thinking PowerShell and wanted to use it to rename the files to be in the right order. In your case, you may need a solution like this anyway because you may not have a choice.

How to rename files to be in the reverse order?

Thinking just logic, here is the idea that I dismissed because it is too complex

  • Take the first file and rename it to be the last files filename
  • Take the second file and rename it to be the second to last filename
  • ..
  • Take the last file and rename it to be the first files filename

There are a bunch of complications with this approach because you have to have two loops and create a mapping. Not only that, you need an intermediate filename each time you rename because two files cannot have the same filename..etc., etc.,

Simpler Logic (preserving part of original file name)

  • Loop through the files in order
  • Start with a big number and rename the first subtracting the big number
  • Increase the big number by 2 (to offset for decreasing file number)
  • Rename the next and keep renaming in the loop until the last one decrementing each time by 2

I know I am not explaining it well here but is the logic

$folder = "E:\Videos\20221216_StageEvent"
$fileList = Dir "$folder\Img_6*.*" | Sort-Object name
$startToEndOffset = 200

foreach ($file in $fileList)
{
    $origFileName = $file.Name
    $origFileNumber = [int]::Parse(($file.Name).Substring(4,4))
    $newFileNumber = $origFileNumber-$startToEndOffset    
    $startToEndOffset+=2

    $newFileName = $origFileName.Replace($origFileNumber.ToString(), $newFileNumber.ToString())
    "$origFileName = $newFileName"
    #Rename-Item -Path $file.FullName -NewName $newFileName
}

The results of the above as to how they will be renamed is below. On the left is the original file name and the new name is on the right.

IMG_6246.MOV = IMG_6046.MOV   --> Notice the new file name starts with a big number
IMG_6247.MOV = IMG_6045.MOV
IMG_6248.MOV = IMG_6044.MOV
IMG_6249.MOV = IMG_6043.MOV
IMG_6250.MOV = IMG_6042.MOV
IMG_6251.MOV = IMG_6041.MOV
IMG_6252.MOV = IMG_6040.MOV
IMG_6253.MOV = IMG_6039.MOV
IMG_6254_Blurry.MOV = IMG_6038_Blurry.MOV
IMG_6255.MOV = IMG_6037.MOV
IMG_6256.MOV = IMG_6036.MOV
IMG_6257.MOV = IMG_6035.MOV
IMG_6258.MOV = IMG_6034.MOV
IMG_6259.MOV = IMG_6033.MOV
IMG_6260.MOV = IMG_6032.MOV
IMG_6261.MOV = IMG_6031.MOV
IMG_6262.MOV = IMG_6030.MOV   --> Notice the new file name ends with a small number

Notice how the last file now has the smallest alphabetical name and the first one the largest alphabetical name!

Need a clean start to file names? Simplify further..

You could even rename them completely to have a different name all together! In this case, I start with a value of 1000 and start going up.

$folder = "E:\Videos\20221216_StageEvent"
$fileList = Dir "$folder\Img_6*.*" | Sort-Object name
$startFileNumber = 1000 + $fileList.Count

foreach ($file in $fileList)
{
    $origFileName = $file.Name
    $origFileNumber = [int]::Parse(($file.Name).Substring(4,4))
    $newFileNumber = $startFileNumber
    $startFileNumber--

    #$newFileName = $origFileName.Replace($origFileNumber.ToString(), $newFileNumber.ToString())
    $newFileName = "FRESHNAME_$($newFileNumber.ToString()).MOV"

    "$origFileName = $newFileName"
    #Rename-Item -Path $file.FullName -NewName $newFileName
}

This produces the below output but file names are much cleaner (look from last file to first). Again, on the left is the original file name and the new name is on the right.

IMG_6246.MOV = FRESHNAME_1017.MOV
IMG_6247.MOV = FRESHNAME_1016.MOV
IMG_6248.MOV = FRESHNAME_1015.MOV
IMG_6249.MOV = FRESHNAME_1014.MOV
IMG_6250.MOV = FRESHNAME_1013.MOV
IMG_6251.MOV = FRESHNAME_1012.MOV
IMG_6252.MOV = FRESHNAME_1011.MOV
IMG_6253.MOV = FRESHNAME_1010.MOV
IMG_6254_Blurry.MOV = FRESHNAME_1009.MOV
IMG_6255.MOV = FRESHNAME_1008.MOV
IMG_6256.MOV = FRESHNAME_1007.MOV
IMG_6257.MOV = FRESHNAME_1006.MOV
IMG_6258.MOV = FRESHNAME_1005.MOV
IMG_6259.MOV = FRESHNAME_1004.MOV
IMG_6260.MOV = FRESHNAME_1003.MOV
IMG_6261.MOV = FRESHNAME_1002.MOV
IMG_6262.MOV = FRESHNAME_1001.MOV

Conclusion:

It is not a big deal if you just have a few files to rename but if you have hundreds or even thousands of files, this is logic that can come in handy. Please do backup the files before you rename “en masse” (or at least have the mapping of what you did to reverse things if needed)!

Advertisement

One thought on “PowerShell: How To Reverse Alphabetical File Names & Rename

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s