2

I regularly have to rename hundreds of files across a subfolder structure. I have been creating a batch file consisting of all my rename commands, and manually pasting this into each subfolder to execute one subfolder at a time. I'd like to revise the batch script so that it executes against all subfolders in one fell swoop, run from the parent directory just once.

My renaming is very manual, and so I need to create a discrete entry for each file. For example, here are three lines:

REN STWP01_00669087* BCBSRI-01849351*
REN BCBSRI-01849357* 2011-12-19_BCBSRI-01849357*
REN STWP01_00669094* BCBSRI-01849369*

I've experimented with the FOR /R command, including trying a separate batch file that calls my renaming batch file (via the CALL command). No luck.

I have to assume that this is simple, but I'm a batch novice, so any help would be appreciated.

Thanks!


@Magoo,

Thanks so much for your response. Your approach is going to be far more efficient than my own so far.

A couple of questions. Please bear with me as I am a total novice with batch commands.

Here's what I did: I saved your code to a .BAT file ("RRename.bat"), modified my filenames as per your instructions and saved those to a text file ("Filenames.txt"), and then run this command from the command line: {RRename.bat Filenames.txt}.

The resulting command windows confirm correct renaming. And so I removed the ECHO and PAUSE commands and re-ran. No luck. Just a bunch of Command windows confirming the directory.

Ideally I'd love to save this as a .BAT file and simply drop this in the top-level directory, together with the data file that contains the old names and new names of the files. And so, a double-click of "RRename.bat" will parse the content of "Filenames.txt" and work its way through all subfolders, renaming wherever matches are encountered. Boom.

To that end:
1. How do I make it so {SET "sourcedir=} indicates the current directory (i.e. the directory in which the batch file is located)? This way I wouldn't ever need to change this variable. (I should note that I am running this script on a network location, which requires me to map the drive, resulting in a different drive letter every time.)
2. How do I hard-code the name of the data file into the script itself? My goal is an easily replicated process minimizing user input (save for the content of the data file).
3. How do I stop the individual command windows from appearing? I'll be renaming thousands of files at a time and don't want to see thousands fo corresponding command windows.

Thank you!

lneidorf
  • 29
  • 3
  • Have you considered PowerShell? If you have systematic way of renaming then you can program it in PowerShell script else if you can provide the actual file name and the name it should be renamed to in a csv file then again a PowerShell script can achieve it. If you give us an example of how you rename it then may be someone can give you some code too. – Junaid Sep 22 '16 at 04:09
  • See [this answer](http://stackoverflow.com/questions/8397674/windows-batch-file-looping-through-directories-to-process-files/8398621#8398621) for another, simpler way to do this process... – Aacini Sep 23 '16 at 11:35

1 Answers1

2
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:: read parameters
SET "filename1=%~1"
SET "filename2=%~2"
IF DEFINED filename2 GOTO name
IF NOT DEFINED filename1 GOTO :EOF
:: 1 parameter - must be filename
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO START /min "ren %%a" "%~f0" %%a
GOTO :eof

:: we have 2 parameters so rename pattern 1 to pattern 2

:name
FOR /r "%sourcedir%" %%a IN ("%filename1%*") DO CALL :process "%%a"
PAUSE

GOTO :EOF

:: Process the filenames and actually do the rename
:process
:: Name of file to be changed - name and extension of %1
SET "changeme=%~nx1"
:: REPLACE up-to-from-pattern with nothing = remainder of name/extension
CALL SET "endpart=%%changeme:*%filename1%=%%"
:: and RENAME...
ECHO(REN "%~1" "%filename2%%endpart%"
GOTO :eof

You would need to change the setting of sourcedir to suit your circumstances.

Revised data file

STWP01_00669087 BCBSRI-01849351
BCBSRI-01849357 2011-12-19_BCBSRI-01849357
STWP01_00669094 BCBSRI-01849369

Aimed at processing the above file, renaming files starting (column1 entries) to start (column2 entries.)

Method:

Run the batch as

batchname filename

This will execute the batch, processing filename

How:

having set the directory name to start processing from, set filename1&2 to the values of the parameters supplied.

If only 1 is supplied, it is the filename, so process it line-by-line and START a new process /min minimised "with the window name in the first set of quotes" and execute this same batch with the data from each line of the file in turn, then finish by going to :eof (end-of-file - built-in to CMD)

The sub-processes all have 2 parameters (eg BCBSRI-01849357 2011-12-19_BCBSRI-01849357) so processing passes to :name. This runs a for /r loop, from the specified source directory, with the name specified from the first column+* and executes :process passing the filenames found as parameter 1.

:process sets changeme to the filename in question, calculates endpart by removing the string filename1 from changeme which will deliver the er, end part.

Then simply rename the supplied filename to the replacement name+that endpart calculated.

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.

The PAUSE is just to allow the proposed changes to be seen. Once the process has been verified, change the PAUSE to EXIT.

AAMOI, running

*batchname* STWP01_00669094 BCBSRI-01849369

for instance, would execute the recursive-rename from STWP01_00669094* to BCBSRI-01849369*


Sadly, "No luck" is meaningless.

I have made a minor, but significant change to the instructions. The PAUSE should be changed to an EXIT after testing.

After testing, the ECHO(... line should become

REN "%~1" "%filename2%%endpart%"

which actually executes the rename. If you've just deleted the line, it would explain the no-visible-result.

Having restored the original code and verified against a small representative dummy subtree, change the echo(... line and test again. The filenames should change. If not, something is dreadfully wrong. Needless to say, this works perfectly happily for me...

Then try again with the PAUSE changed to EXIT. This time, the windows generated will appear on the taskbar and then disappear when the rename for that line of the input file has finished. This will happen once for BCBSRI-01849357 rentwo for instance - not once for each individual file rename occurring.

To hard-code the filename, remove the line

IF NOT DEFINED filename1 GOTO :EOF

and replace

FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO START /min "ren %%a" "%~f0" %%a

with

FOR /f "usebackqdelims=" %%a IN ("YOURFILENAMEHERE") DO START /min "ren %%a" "%~f0" %%a

For the "run from here" command, change

SET "sourcedir=U:\sourcedir"

to

SET "sourcedir=."

. means "the current directory"

If you place thisbatchfilename.bat into any directory on your PATH then you can run the routine simply by executing thisbatchfilename.

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 chane path, google "change path windows" - experienced batchers create a separate directory on the path for batch files. Sometimes, they name the directory "Belfry".

Magoo
  • 77,302
  • 8
  • 62
  • 84