Renaming files in a folder with incrementing number in PowerShell
Quite often I find myself having to rename a bunch of files in a folder, and what better way to do this than PowerShell? This simple one-liner is also a great way to learn a few new PowerShell tricks, or rather- get familiar with the syntax and see how flexible PowerShell is.
The script I’m working on is rather long, and not finished, so for now I’ll just share this handy little snippet.
To rename all my files in a folder called blog I navigate to the folder in question and wrote this in PowerShell
powershell_rename_files_numbers
$nr = 1
Dir | %{Rename-Item $_ -NewName (‘MyFile{0}.txt’ -f $nr++)}
Let’s walk through everything in those lines!
$nr = 1
Sets a variable called nr with the value of 1
Dir
is the content of current directory , unless path is specified as –path like so:
Dir -path C:\Users\IrisDaniela\Pictures\Blog| %{Rename-Item $_ -NewName (‘File{0}.txt’ -f $nr++)}
You could also use Get-ChildItem (gci) or ls
|
Pipe will pass the output from the previous function to whatever we call next
% { }
does a foreach
Rename-Item
renames the item
-NewName
is where we define the new name
()
Is used here for grouping since the -NewName expects one input of type string
{0}
is used for formatting as in C# together with
-f
Whatever we define after -f will replace {0}
You can have {0}{1} and so on, just separate the strings after -f with a comma like so: -f “I’m firs”, “I’m second”
++
is an increment operator, and here it will increment the $nr variable
What the line above is saying is:
I want the start number to be one, and for each item in this directory I want to rename the item with a new name that is MyFile{some number}.text and incrementing the number so we can name the files MyFile1.txt, MyFile2.txt until we have gone through all the items
Comments
I really like that we can format the strings so easily, helps giving photos decent names. I use that for naming photos on the blog for SEO.
Nice stuff in PowerShell, the same command in Bash: $ ls *.txt | awk 'BEGIN{i=0} {printf "mv %s TextFile%d.txt\n", $0, i++}' | bash
Unfortunately, the foreach doesn't run through the files in the order in which they appear. I'm trying to replace the original file number (which came in on a data feed and so have numbering from that) with 1-based numbering for several subsets. The resulting files are not in the original order.
Use filtering and pipe the filtered result ordered by what you need to a function that does the renaming (make the renaming as a function)
Thanks, i've made a simple script with your explanation:
function changeName{
$n = $args[0];
$name = $args[1];
Dir | %{Rename-Item $_ -NewName ($name+‘{0}.jpg’ -f $n++)}
}
Last modified on 2013-12-14