Batch file to rename files with a counter and specific filenames

74 Views Asked by At

I'm trying to create a batch file that I can copy and paste into any folder (I don't want to have to change the directory path every time I use it) that has multiple jpg files in it such that when I run the .bat file, it will rename all the jpg filenames in that folder with a specific title keeping the jpg files in the same order as they were originally. I want the first jpg in the folder to be renamed as 1 - Front, then the next jpg to be renamed as 2 - Back, then the next jpg to be renamed as 3 - Left Side, then the next jpg to be renamed as 4 - Right Side, then the next jpg to be renamed as 5 - Top, then the next jpg to be renamed as 6 - Bottom

I've tried 4 scripts. The first:

@echo off
setlocal enabledelayedexpansion

REM Get the current directory where the batch file is located
set "folderPath=%~dp0"

REM Initialize the counter
set "counter=1"

REM Define the desired filenames
set "filenames=Front Back Left Side Right Side Top Bottom"

REM Loop through each JPG file in the folder
for %%F in ("%folderPath%\*.jpg") do (
    REM Rename the file based on the counter and filenames
    for %%A in (!counter!) do (
        ren "%%F" "%%A - !filenames:~%%A,1!.jpg"
    )
    REM Increment the counter
    set /a "counter+=1" 
)

This renames the first file as 1 - r, the second file as 2 - o, the third file as 3 - n, the fourth file as 4 - t, the fifth file as 5 - , and the sixth file as 6 -

I also tried this:

@echo off
setlocal enabledelayedexpansion

REM Get the current directory where the batch file is located
set "folderPath=%~dp0"

REM Initialize the counter
set "counter=1"

REM Define the desired filenames
set "filenames=Front Back Left Side Right Side Top Bottom"

REM Loop through each JPG file in the folder
for %%F in ("%folderPath%\*.jpg") do (
    REM Get the corresponding filename from the list
    for %%A in (!counter!) do (
        for %%B in (!filenames!) do (
            if %%A==1 (
                ren "%%F" "%%A - %%B.jpg"
            ) else (
                REM Increment the counter
                set /a "counter+=1"
                if %%A==2 (
                    ren "%%F" "%%A - %%B.jpg"
                ) else (
                    REM Increment the counter
                    set /a "counter+=1"
                    if %%A==3 (
                        ren "%%F" "%%A - %%B.jpg"
                    ) else (
                        REM Increment the counter
                        set /a "counter+=1"
                        if %%A==4 (
                            ren "%%F" "%%A - %%B.jpg"
                        ) else (
                            REM Increment the counter
                            set /a "counter+=1"
                            if %%A==5 (
                                ren "%%F" "%%A - %%B.jpg"
                            ) else (
                                REM Increment the counter
                                set /a "counter+=1"
                                if %%A==6 (
                                    ren "%%F" "%%A - %%B.jpg"
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)

This renames the files as 1 - Back, 1 - Front, 1 - Left, 1 - Right, 1 - Side, 1 - Top.

Next, I tried:

@echo off
setlocal enabledelayedexpansion

REM Get the current directory where the batch file is located
set "folderPath=%~dp0"

REM Initialize the counter
set "counter=1"

REM Define the desired filenames
set "filenames=Front Back Left Side Right Side Top Bottom"

REM Loop through each JPG file in the folder
for %%F in ("%folderPath%\*.jpg") do (
    REM Rename the file based on the counter and filenames
    for %%A in (!counter!) do (
        for %%B in (!filenames!) do (
            if %%A==%%B (
                ren "%%F" "%%A.jpg"
            )
        )
    )
    REM Increment the counter
    set /a "counter+=1" 
)

And finally, I tried:

@echo off
setlocal enabledelayedexpansion

REM Get the current directory where the batch file is located
set "folderPath=%~dp0"

REM Define the desired filenames
set "filenames=Front Back Left Side Right Side Top Bottom"

REM Initialize the counter
set "counter=1"

REM Loop through each JPG file in the folder
for %%F in ("%folderPath%\*.jpg") do (
    REM Extract the corresponding filename from the list
    for %%A in (!counter!) do (
        for %%B in (!filenames!) do (
            if %%A==%%B (
                set "newName=%%B.jpg"
                ren "%%F" "!newName!"
            )
        )
    )
    REM Increment the counter
    set /a "counter+=1" 
)

Neither of these last two did anything. Can someone please help? Thanks!

4

There are 4 best solutions below

0
Squashman On BEST ANSWER

This is just one possible way you could do this. Output the new filenames to a temporary file. Then use that as standard input to the code block. This will get captured by the SET /P command. Use a FOR /F command to capture the output of the dir command. It is essential that this is used versus a normal FOR command. All files are enumerated by the FOR /F before it executes. With a normal FOR command it processes one file at a time which will cause issues with files entering back into the queue. I am just echoing the rename to show you what it will do. If it looks correct just remove the echo from the rename command.

@echo off
setlocal enabledelayedexpansion
REM List JPG files in directory
dir /a-d /b /on *.jpg
(
echo 1 - Front
echo 2 - Back
echo 3 - Left
echo 4 - Right Side
echo 5 - Top
echo 6 - Bottom
)>tmp.txt

<tmp.txt (FOR /F "delims=" %%G IN ('dir /a-d /b /on *.jpg') DO (
    set /p newname=
    echo rename "%%G" "!newname!%%~xG"
    )
)
del tmp.txt

Here is the execution.

D:\My Drive\BatchFiles\SO\78206913>so.bat
bar.jpg
foo.jpg
green.jpg
pink.jpg
purple.jpg
red.jpg
rename "bar.jpg" "1 - Front.jpg"
rename "foo.jpg" "2 - Back.jpg"
rename "green.jpg" "3 - Left.jpg"
rename "pink.jpg" "4 - Right Side.jpg"
rename "purple.jpg" "5 - Top.jpg"
rename "red.jpg" "6 - Bottom.jpg"
1
Stephan On

Your main problem is that you try to iterate on two independent lists in parallel. Loops aren't that smart in batch, so you have to trick them: use a single thing to loop through (!c!) and use it to get the correct/same entry from both lists (number and suffix (what you called "filename")).

You said you want to keep the original order of the files, but didn't specify by what criteria, so I took a guess (two actually; by date or by name, see the comments).

@echo off
setlocal enabledelayedexpansion

REM get a bunch of files to test
for %%a in (first,second,third,fourth,sixth,seventh,eighth) do (break>%%a.jpg&timeout 1 >nul)

REM Get the current directory where the batch file is located
rem set "folderPath=%~dp0"
pushd "%~dp0"

REM Define the desired filenames
set "filenames=Front Back "Left Side" "Right Side" Top Bottom"

REM build an array from "filenames"
set c=0
for %%a in (%filenames%) do (
  set /a c+=1
  set "filename[!c!]=%%a"
)
rem set filename

REM rename the files sorted by creation time (change /od`to `on`to sort by name)
REM and filter already renamed files (do not rename twice)
set c=0
for /f "delims=" %%a in ('dir /b /a-d /od *.jpg ^|findstr /v "%filenames:"=\"%"') do (
   set /a c+=1
   call ECHO ren "%%a" "!c! - %%filename[!c!]%%.jpg"
)

The ren command is disabled by just echoing it. Remove the ECHO when you're sure it does what you want.

Output of the above script:

ren "first.jpg" "1 - Front.jpg"
ren "second.jpg" "2 - Back.jpg"
ren "third.jpg" "3 - Left.jpg"
ren "fourth.jpg" "4 - Side.jpg"
ren "sixth.jpg" "5 - Right.jpg"
ren "seventh.jpg" "6 - Side.jpg"
ren "eighth.jpg" "7 - Top.jpg"
3
Squashman On

Here is on other possible solution. In this instance a map is created of the new file names and the original file names. Then a FOR /L command is used to iterate the file mappings. Remove the echo before the rename if you are happy with the output

@echo off
setlocal enabledelayedexpansion

REM Create New file map
SET map=1-Front;2-Back;3-Left;4-Right Side;5-Top;6-Bottom

REM Create file map
set "fmap="
set "cnt=0"
FOR /F "delims=" %%G in ('dir /a-d /b /on *.jpg') do (
    set /a cnt+=1
    set "fmap=!fmap!;!cnt!-%%G"
)

REM Iterate both maps
FOR /L %%G IN (1,1,6) DO (
    CALL :map %%G
)

GOTO :EOF
REM ONLY FUNCTION ALLOWED BEYOND THIS LINE

:map
REM getting the new file name
CALL SET v=%%map:*%1-=%%
SET v=%v:;=&rem.%

REM getting the original file name
CALL SET f=%%fmap:*%1-=%%
SET f=%f:;=&rem.%
ECHO. rename "%f%" "%1 - %v%.jpg"

GOTO :EOF

Here is the output.

D:\My Drive\BatchFiles\SO\78206913>so3.bat
 rename "bar.jpg" "1 - Front.jpg"
 rename "foo.jpg" "2 - Back.jpg"
 rename "green.jpg" "3 - Left.jpg"
 rename "pink.jpg" "4 - Right Side.jpg"
 rename "purple.jpg" "5 - Top.jpg"
 rename "red.jpg" "6 - Bottom.jpg"

Note: The only drawback to this method is if the original file names have the map delimiter character (hyphen) in them this will fail. So you would need to switch out the hyphen with a character that is not in the file names. Just for the fmap.

0
Magoo On
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "newnames=Front Back "Left Side" "Right Side" Top Bottom"

FOR /f "tokens=1*delims=:" %%b IN (
 'dir /b /a-d "%sourcedir%\*.jpg" ^|findstr /n "."'
 ) DO SET /a count=0&FOR %%q IN (%newnames%) DO SET /a count+=1&IF %%b==!count! ECHO REN "%%c" "%%b - %%~q%%~xc"
)

GOTO :EOF

simply tokenise a list of the filenames created by dir (you can set the order of filenames by using the /o option - see dir /? from the prompt for options) which has been prefixed by findstr with line_number: (/n switch) so %%b receives the number and %%c the filename.

clear the counter for each line, then count the entries in newname and rename on a match.

You would need to change the value assigned to sourcedir to suit your circumstances. The listing uses a setting that suits my system. In the circumstances outlined, it would be set to . (the current directory)

The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.

You do not need to copy the batch into your target directory. If the batch is located in any directory on the path, windows will locatw it.

You can display your path by typing

path

at the prompt. PATH is the sequence of directories searched by windows to find an executable if it isn't found in the current directory. To change path, use "set path=newdirectory;%path%" which appends the current path to the new directory.

Experienced batchers create a separate directory on the path for batch files. Sometimes, they name the directory "Belfry".