Windows – Renaming files in a folder in Windows using Powershell

powershellwindows

In a directory, I have some .jpg files.

  • The file names are integers starting from 1.jpg to 150.jpg.

  • I would like to subtract 1 from each file name.

  • So the file names would be 0.jpg to 149.jpg.

I know how to replace some characters in the file name using PowerShell.

How can I achieve this with Powershell?

Following are the Powershell scripts which I tried.

Powershell Script

gci *.jpg | rename-item -newname {[integer]($_.name -replace ".JPG", "")-1}

And:

gci *.JPG | rename-item -newname { (([convert]::ToInt32($_.name, 10)) - 1) + ".JPG"}

Best Answer

File names should be like 0.jpg to 149.jpg

Use the following PowerShell command:

dir *.jpg | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) } | foreach-object -begin { $count=0 } -process { rename-item $_ -NewName "$count.jpg"; $count++ }

Notes:

  • $count=0 start counting from 0.
  • $_ represents each item passed to the rename-item command via the pipe | from the dir command.
  • foreach-object allows you to set a variable ($count) before looping through each file in the directory (matching *.jpg) and then perform an action (rename-item) for each matching item.
  • To sort the dir output in a "natural" sort order, we use:

    Sort-Object { [regex]::Replace($_.Name, '\d+', { args[0].Value.PadLeft(20) }) }
    

Example:

PS F:\test> dir *.jpg

    Directory: F:\test

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        01/04/2016     19:39         54 1.jpg
-a---        01/04/2016     19:39         54 10.jpg
-a---        01/04/2016     19:39         52 11.jpg
-a---        01/04/2016     19:39         54 2.jpg
-a---        01/04/2016     19:39         54 3.jpg
-a---        01/04/2016     19:35         52 4.jpg
-a---        01/04/2016     19:35         52 5.jpg
-a---        01/04/2016     19:39         51 6.jpg
-a---        01/04/2016     19:39         51 7.jpg
-a---        01/04/2016     19:39         54 8.jpg
-a---        01/04/2016     19:39         52 9.jpg


PS F:\test> dir *.jpg | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) } | foreach-object -begin { $count=0 } -process { rename-item $_ -NewName "$count.jpg"; $count++}

PS F:\test> dir *.jpg

    Directory: F:\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        01/04/2016     19:39         54 0.jpg
-a---        01/04/2016     19:39         54 1.jpg
-a---        01/04/2016     19:39         52 10.jpg
-a---        01/04/2016     19:39         54 2.jpg
-a---        01/04/2016     19:35         52 3.jpg
-a---        01/04/2016     19:35         52 4.jpg
-a---        01/04/2016     19:39         51 5.jpg
-a---        01/04/2016     19:39         51 6.jpg
-a---        01/04/2016     19:39         54 7.jpg
-a---        01/04/2016     19:39         52 8.jpg
-a---        01/04/2016     19:39         54 9.jpg

PS F:\test>

Source: Batch File Rename with Windows PowerShell. Script has been tweaked to match the requirements of the question.

Source: How to sort by file name the same way Windows Explorer does? answer by Roman Kuzmin for natural sorting.

Related Question