Number Within Sub-Folders

See Also: Unique Numbers rename script

This script renames files using a counter, so each file is numbered.

  • Note: There are much easier ways to do that if you just want simple numbering. You don't even need a script! Just turn on the Sequential numbering from... checkbox and put [#] in the filename where you want the numbers to appear.

What makes the script special is how it handles files that are in different folders: Instead of using a single counter for the entire operation, it uses a separate counter for each folder.

  • Opus 12 and above: You don't need this script. The basic Sequential numbering from... option already works this way by default now, if renaming files in sub-folders. (Select the folders and tell the rename dialog to rename their contents; don't select the files from Flat View or similar, unless you want the old behavior.) The script may be useful as the basis for something more esoteric.

The rename preset (which packages the script) also adds the 1st and 2nd parent folder names to each file name. If you don't want that, just change the Old Name and New Name fields appropriately. (You should not have to edit the VBScript part at all.)


Here's a before and after example:

(Jan 2016 update) The script now also works if the rename itself moves the files around, e.g. to sort photos by shooting time and then number them within the new dated folders.

Here's a screenshot of the rename dialog, including a preview of what it'll do:

In this case, I did the following:

  • Starting from a lister, I selected the "Root" folder.
  • Clicked Rename on the toolbar.
  • Selected my rename preset in the Rename dialog.
  • Turned on Rename files in selected sub-folders, then, to make the preview include child items:
    • Opus 12: Turned on Show preview of sub-folder contents as well.
    • Opus 11: Clicked the Full Preview button.

You could also achieve similar results like this:

  • Starting from a lister, go into the "Root" folder.
  • Either turn on Flat View or perform a Find so you have a list of all files below that point.
  • Select everything and click Rename on the toolbar.
  • Select the rename preset in the Rename dialog.

It does not matter whether you choose to get the list of files up-front or have the Rename window get it. They are simply two ways of achieving the same thing.

Opus 12: If you are using the built-in Sequential numbering from... option instead of the script, the way you get the files into the Rename dialog does matter:

  • If you select folders and turn on Rename files in selected sub-folders, a separate count will be used for each folder (like the script does).
  • If you use Flat View and select all the files to rename them, a single count will be used for all the files.

Controlling where the numbers go:

When using the preset, put [NUM] in the filename where you want the numbers to appear.

  • Important note: The script looks for [NUM] case sensitive. You need to enter it exactly, all in upper case.
  • If you're using Rename dialog options which change the case of filenames at the same time as the script, you will need to edit the script slightly so it looks for the right thing.



  • 08/Jan/2016: Updated to handle renames which move files into new folders. The script now takes the new folders into account, not just the starting folders.
  • 22/Sep/2011: First version.

Script code for reference:

This is just for reference, so people who want to see how the script code works do not have to download and install the preset.

If you just want to use the script, download the .orp file above, and ignore this part.

Option Explicit

' Some configuration paramters:

Dim NumberPattern
Dim StartingNumber
Dim PadTo

' The script will find this pattern in the filename and replace
' it with the next number in the sequence. Use the Old Name and
' New Name fields in the Opus rename dialog to add [NUM] into
' the new name. Remember that you can still use the "Enable file
' information fields" option to insert metadata, such as
' {shootingtime} (when a photo was taken) into the new filename.
NumberPattern = "[NUM]"

' First number to try. Usually 1.
StartingNumber = 1

' Number of digits to pad the number to. For example, if PadTo
' is 3 then the script will generate 001, 002, 003, 004, etc..
PadTo = 3

Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")

Dim FolderCounts
Set FolderCounts = CreateObject("Scripting.Dictionary")

' Make the dictionary case-insensitive (1==TextCompare)
FolderCounts.CompareMode = 1

Function Rename_GetNewName(strFileName, strFilePath, fIsFolder, strOldName, ByRef strNewName)

	Dim bAbsolutePath
	Dim strNum
	Dim strTryNewName
	Dim strTryNewFullPath
	Dim bNeedLoop
	Dim num
	Dim parentFolderKey

	' Make sure folders are left completely alone.
	If (fIsFolder) Then
		strNewName = strFileName
		Exit Function
	End If

	If PadTo < 1 Then
		PadTo = 1
	End If

	' Work out if the new path is relative to the original path or if it's an absolute path.
	' For example, a rename from * to C:\* would move files to the root of C:\
	If strNewName = fs.GetAbsolutePathName(strNewName) Then
		bAbsolutePath = True
		bAbsolutePath = False
	End If

	parentFolderKey = fs.GetParentFolderName(strNewName)
	If (parentFolderKey = "") Then
		parentFolderKey = strFilePath
	End If

	num = FolderCounts.Item(parentFolderKey)
	If (IsEmpty(num)) Then
		num = StartingNumber
	End IF

	bNeedLoop = True

	While bNeedLoop
		' Replace the NumberPattern with the current number.
		strNum = CStr(num)
		If Len(strNum) < PadTo Then
			strNum = String(PadTo - Len(strNum), "0") & strNum
		End If

		strTryNewName = Replace(strNewName, NumberPattern, strNum)

		If strTryNewName = strNewName Then
			DOpus.OutputString NumberPattern & " not found in " & strNewName
			Exit Function ' Number pattern wasn't found so stop now.
		End If

		' Work out the full path to the new filename.
		If bAbsolutePath Then	
			strTryNewFullPath = strTryNewName
			strTryNewFullPath = fs.BuildPath(strFilePath, strTryNewName)
		End If

		num = num + 1

		' Check if the new filename already exists.
		If ((not fs.FileExists(strTryNewFullPath)) and (not fs.FolderExists(strTryNewFullPath))) Then
			FolderCounts.Item(parentFolderKey) = num
			strNewName = strTryNewName
			DOpus.OutputString "Generated name: " & strNewName
			bNeedLoop = False
		End If

End Function
1 Like

Jan 2016 update: The script now also works if the rename itself moves the files around, e.g. to sort photos by shooting time and then number them within the new dated folders.