2

The company I work for processes bills, and I regularly have to check these bills for accuracy by comparing what was entered into the database vs. the actual bill image. Any time I find an error in processing, I must delete the bill from the database and send the image to a processor to re-enter the bill correctly. However, our system frequently encounters a glitch where if I try to upload the bill to the server that gets it to the processor, it says that a duplicate file exists. To bypass this issue I have to manually rename each image with a new name (we use rolls of control numbers to name our images).

I'd like to automate this process so that I can rename these files quickly in sequential order. I would like my batch file to have an input so that I can enter in the starting control number and it will rename each file in the directory in sequential order, starting with the control number I enter +1 to each additional file in the directory, for example it would go like this:

Batch file asks me starting control #. I enter in 6654821.

  • bill3210851.pdf renamed to 6654821
  • imagebill654.pdf renamed to 6654822
  • random_name.pdf renamed to 6654823
  • billerror.pdf renamed to 6654824
  • sendtomanual.pdf renamed to 6654825

The original name of the file is not at all relevant, they don't need to remain in any specific order as long as they are renamed sequentially.

So far what I have is this:

@echo OFF
title Batch Rename
color 5f

echo Hello! I'm the batch pdf renamer. Please enter the starting control number:
set /p start=

ren %userprofile%\desktop\needrenamed\*.pdf "%p%.pdf"

pause

Obviously this doesn't address renaming the files sequentially. I'm kind of stuck here.

1
  • How about using a 3rd party utility like Bulk rename tool? Follow this link and find out more. This tool will give the flexibility you need
    – Prasanna
    Nov 14, 2014 at 3:17

5 Answers 5

1

This has been tested in Windows 7 Professional. No error checking of any kind is performed. It renames the files in the current directory, so the script should be somewhere on your path.

@echo off
set /p start=Please enter the starting control number: 

setlocal enableDelayedExpansion

for /r %%g in (*.pdf) do (call :RenameIt %%g)
goto :eof
goto :exit

:RenameIt
echo Renaming "%~nx1" to !start!%~x1
ren "%~nx1" !start!%~x1
set /a start+=1
goto :eof

:exit
exit /b

Hope that helps!

0

I have written this batch script and put it on my Gist Repo. It requires Windows Scripting Host access. Here is the file:

@set @junk=1 /*
@echo off
cscript //nologo //E:jscript %0 %*
goto :eof
*/

var args=WScript.Arguments, shell=WScript.CreateObject("WScript.Shell"), bForced=false, nStartIndex=-1;

if(args.length==0||(args.length==1&&(bForced=args(0).toLowerCase()=='-f'||args(0).toLowerCase()=='--force'))) {
    showHelp();
    WScript.Echo("\nERROR: You must provide a starting value to begin counting at.");
    WScript.Quit(1);
}
if(args(0)=='-?'||args(0).toLowerCase()=='--help') {
    showHelp();
    WScript.Quit(0);
}
if(isNaN(nStartIndex=parseInt(args(bForced?1:0)))||nStartIndex<0) {
    showHelp();
    WScript.Echo(sprintf("\nERROR: The value [%s] which was given for start index is invalid. It should be a positive integer.", nStartIndex));
    WScript.Quit(2);
}

var fso=new ActiveXObject("Scripting.FileSystemObject");
var folder=fso.GetFolder(shell.CurrentDirectory);
var enFiles=new Enumerator(folder.Files);
var oFile, file_path, file_ext;

if(!bForced) {
    for(var nCurDX=nStartIndex; !enFiles.atEnd(); enFiles.moveNext(), nCurDX++) {
        oFile=enFiles.item();
        file_path=oFile.Name;
        file_ext=getFileExt(file_path);
        WScript.Echo(sprintf("Rename %s to %s", file_path, nCurDX+file_ext));
    }
    WScript.Echo("Type 'yes' to continue...");
    if(WScript.StdIn.ReadLine().toLowerCase()!="yes") {
        WScript.Echo("\nAction cancelled by user.");
        WScript.Quit(-1);
    }
    enFiles=new Enumerator(folder.Files);
}

for(var nCurDX=nStartIndex; !enFiles.atEnd(); enFiles.moveNext(), nCurDX++) {
    oFile=enFiles.item();
    file_path=oFile.Name;
    file_ext=getFileExt(file_path);
    try {
        oFile.Name = nCurDX+file_ext;
    } catch(e) {
        WScript.Echo(sprintf("\nERROR: Cannot rename file:\n\t%s\n\nReason: %s\n", file_path, e.description));
        WScript.Quit(3);
    }
}

/////////////////////////////////
/////////// FUNCTIONS ///////////
/////////////////////////////////

function sprintf(format, etc) { var arg=arguments, i=1; return format.replace(/%((%)|s)/g, function (m) { return m[2] || arg[i++] }); }
function showHelp() {
    WScript.Echo("------------------");
    WScript.Echo("Numeric Rename All");
    WScript.Echo("------------------");
    WScript.Echo("");
    WScript.Echo("This file will change the file title of all files is a directory");
    WScript.Echo("so that they are all just an incremented number with the original");
    WScript.Echo("extension still in place.");
    WScript.Echo("");
    WScript.Echo("Usage: NUMERIC_RENAME_ALL [ -? | --help ] [ -f | --force ] <start-index>");
    WScript.Echo("");
    WScript.Echo("\t-?, --help\tDisplay this help screen and exit.");
    WScript.Echo("");
    WScript.Echo("\t-f, --force\tRename the files without prompting first.");
    WScript.Echo("");
    WScript.Echo("\t<start-index>\tThe value to begin counting at.");
    WScript.Echo("");
    WScript.Echo("This script takes one parameter and that is the number to begin at.");
    WScript.Echo("For example (if called with 12345 as the parameter):");
    WScript.Echo("");
    WScript.Echo("\ttest1.jpg becomes 12345.jpg");
    WScript.Echo("\ttest1.jpg.txt becomes 12346.jpg.txt");
    WScript.Echo("\ttest2.pdf becomes 12347.jpg");
    WScript.Echo("");
    WScript.Echo("Currently, there is no way to sort the items and they will be");
    WScript.Echo("numbered according to the default file order for your system.");
    WScript.Echo("");
    WScript.Echo("----------------------");
}
function getFileExt(file_path) {
    var dx=file_path.lastIndexOf("\\"), ret;
    if(dx==-1) dx=file_path.lastIndexOf("/");
    ret=file_path.substring(dx+1);
    return (dx=ret.indexOf("."))==-1?"":("."+ret.substring(dx+1));
}

Save it as NUMERIC_RENAME_ALL.BAT in a place easy to get to.

Doing this in a plain batch file would be difficult because cmd.exe fails at setting variable inside of loops. This is why we are using a Batch\WSH Hybrid file to do this (this is declared in those first 5 lines of the script). There is probably a fairly easy way to do this is power shell too.

1
  • The Gist page has now been updated to support the use of regular expressions in order to select files to be renamed instead of always renaming them all.
    – krowe
    Nov 14, 2014 at 7:25
0
@echo off
    setlocal enableextensions disabledelayedexpansion

    set /p "number=Please enter the starting control number:" || goto :eof

    for /f "delims=" %%a in ('dir /b *.pdf') do (
        setlocal enabledelayedexpansion
        for %%b in (!number!) do (
            endlocal
            echo ren "%%~fa" %%b
        )
        set /a "number+=1"
    )

For each .pdf file in the current folder, rename the file to the current number and increase the number.

Rename operations are only echoed to console. If the output is correct, remove the echo that prefixes the ren command.

0

I found this question while looking for a means to sequentially rename all files in each subfolder recursively, but where I required the numbers to be padded with leading zeros, and also to be agnostic to the file extension. I found a solution here that led me to the final solution which is:

@echo off
setlocal enabledelayedexpansion

for /d /r %%a in (%1\*.*) do (
    set /a counter=0
    for %%b in ("%%a\*.*") do (
        set /a counter += 1
        set zcounter=0000!counter!
        set source="%%~fb"
        set target="Receipt !zcounter:~-4!%%~xb"
        echo Renaming !source! to !target!
        ren !source! !target!
    )
)

Put the above in a batch file and call passing a directory as a parameter. The script pads with up to three leading zeros and prefixes with the word "Receipt", but change according to your requirements. This script will work fine also if you don't have subfolders to recurse into. And if you don't want leading zeros, just remove the set zcounter line, and replace zcounter:~-4 with counter.

Hope this helps anyone stumbling across this page looking for something similar.

0

I tried JSanches”s solution, but did not work for me.

Then tried MC ND’s solution but the output file had no extension.

I did not wanted to do Windows Scripting Host access, so did not tried krowe’s solution,

Last Neo’s solution did not work, but I like the syntax.

I have adapted this to a workable syntax see below. (Note, first time doing batch script, so below are my assumptions).

Open Notepad

Copy text below

Save as “Rename_files.bat” in the same folder where the files are.

Be Happy

@echo off
setlocal enabledelayedexpansion
set /a counter=0
for /r %%a in (%1\*.pdf) do (
    timeout /t 1 nobreak
    echo %%~fa
    set /a counter += 1
    echo ren %%~fa !counter!%%~xa
    set zcounter=0000!counter!
    set source=“%%~fa”
    set target=“Document!zcounter:~-4!%%~xa”
    echo renaming !source! to !target!
    ren !source! !target!
)
timeout /t 3 /nobreak

Explanation

prevent all commands in a batch file (including the echo off command) from displaying on the screen
Enable the delayed environment variable expansion 
define variable counter as 0
for each file (%%a) in (regardless of name but as.pdf) do (
    Delay 1 second
    Display path/file
    increase variable counter +1
    Display message “path/file as counter and maintain extension
    Define zcounter as 0000 with current value of counter
    Define source as path/file
    define  target as Document with value of zcounter up to last 4 characters and maintain file extension.
    Display message “renaming source to target”
    rename source as target
)
Delay 3 seconds

You can most certainly remove all echo and timeout, unless you want to see what is happening.

Also first Display message can remove “echo” text and renames files as numbers only. If you want.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .