Bulk renaming files in relation to the folder names - cmd

I am very new to coding and bulk processes but i am looking for a command line SPECIFICALLY for windows command prompt and i am wondering if such a thing exists. So I have a folder containing 111 subfolders, with each subfolder containing between 20 and 40 png image files. Each subfolder is named 001-111 accordingly and the png files are ordered how i want them, however i am looking for a command line that would be able to quickly and efficiently name all the pngs in the folders to the name of the folder followed by the png number in brackets
e.g. for folder 037, i would want the png's to be renamed to: 037(1), 037(2), 037(3) etc...
I am hoping for the best although i am unsure such a code may not be possible or be simply done.
Also if you come up with a code that achieves this process, it would be great if you could reply with the simple command line that i could use rather than a full explanation because i am new to coding and far from fluent with the language or terms or how things work. I know this same process can be achieved by going select all>rename (ctrl a>f2) and renaming to the folder name however i need to use this process frequently and dont want to have to open each folder, i would rather have a command line for cmd that would do it swiftly
Thank you and a simple answer would be greatly appreciated

#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "parentdir=u:\parent"
FOR /l %%a IN (1001,1,1111) DO (
SET dir=%%a&SET "dir=!dir:~1!"
FOR /f "delims=" %%i IN ('dir /a-d /b "%parentdir%\!dir!\*.png" 2^>nul') DO (
ECHO REN "%parentdir%\!dir!\%%~nxi" "!dir!(%%~ni)%%~xi"
)
)
GOTO :EOF
Test results:
Starting directory :
u:\parent\001\1.png
u:\parent\037\1.png
u:\parent\037\2.png
u:\parent\111\999 with spaces in name.png
Script response
REN "u:\parent\001\1.png" "001(1).png"
REN "u:\parent\037\1.png" "037(1).png"
REN "u:\parent\037\2.png" "037(2).png"
REN "u:\parent\111\999 with spaces in name.png" "111(999 with spaces in name).png"
Obviously, you'd need to replace the value assigned to parentdir with your actual target directory name.
The script will report the renames it proposes to do. To actually invoke the rename remove the ECHO keyword.

I would create a batch file like so:
renamepng.bat:
cd %%1
if ERRORLEVEL 1 goto end
for %f in *.png do mv "%f" "%%1(%f).png"
cd ..
:end
This will attempt to cd to the directory name provided on the command line, abort if that fails, then rename all the .png files and return to the previous directory
then call it like so:
for %d in ??? do call renamepng.bat %d
which will loop through all 3-character file and directory names in the current directory, can call the batch file on each one. Using call instead of just the batch file name causes execution to return to the loop when the batch finishes.

Related

Run Batch Script Across Subfolders (Recursively)

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!
#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".

Windows Batch script to rename files with it's folder name within a for loop

I have a bunch of .flv files in subdirs and I need to loop through them and rename it according to its path.
I was able to loop through them all, but I don't know how to split the path and rename it using batch script.
Here's what I have so far:
echo off
for /R %%F in (*.flv) do (
echo %%~pF
)
The "echo %%~pF" prints the path for the current file on the loop, something like this:
\folder\morefolders\activity\ NameThatIwant \Videos\
I tried spliting with "delims=\" on my for loop but I get only "echo off".
I tried other tutorials, read other questions on SO but none of them were renaming the files from a split string from the path of the file in the loop.
Could you guys help giving suggestions or direct me to any material that explains those %% codes?
Thanks.
I think you do not need to split the path, though you could do it using for /f "delims=NameInthePath tokens=1", where NameInthePath - is some word in the path and tokens= gives you the first part of the path separated by delims.
Actially, if you need to rename file name you need to use REN command. If you need to change the path for the flv file - use copy of move command.
A batch file to rename all .LOG files to .TXT in the 'demo' folder and all sub-folders:
CD C:\demo\
For /R %%G in (*.LOG) do REN "%%G" "%~nG.TXT"

Want to execute command on each file in directory one at a time through batch file windows

I am currently doing this to execute a single command on a particular type of files in directory.
COPY *.prn /B \\\\{$PC}\\{$PRINTER}
The PC And Printer Part is redundant no need to understand that
Instead of executing all files at once I want to be able to do one file at a time through a loop
try this:
for %%i in (*.prn) do COPY "%%~i" /B \\\\{$PC}\\{$PRINTER}
Im not entirely sure what you mean but try this, it will execute the command once for each file in the current directory and (all subdirectories, but this exact snipets not ideal for subdirectories) ending with the extension .prn:
for /r %%a in (*) do (
if %%~xa == .prn (
copy %%~na%%~xa /B \\\\{$PC}\\{$PRINTER}
)
)
Tell me if this doesn't work or you want to do this for subdirectories as well.
Yours, Mona

Windows Batch File Looping Through Directories to Process Files?

I need to write/use a batch file that processes some imagery for me.
I have one folder full of nested folders, inside each of these nested folders is one more folder that contains a number of TIF images, the number of images vary in each folder. I also have a batch file, lets call it ProcessImages.bat for Windows that you can "drop" these TIF files on (or obviously specify them in a command line list when invoking the bat); upon which it creates a new folder with all my images process based on an EXE that I have.
The good thing is that because the bat file uses the path from the folders you "drop" onto it, I can select all the TIFs of one folder and drop it to do the processing... but as I continue to manually do this for the 300 or so folders of TIFs I have I find it bogs my system down so unbelievably and if I could only process these one at a time (without manually doing it) it would be wonderful.
All that said... could someone point me in the right direction (for a Windows bat file AMATEUR) in a way I can write a Windows bat script that I can call from inside a directory and have it traverse through ALL the directories contained inside that directory... and run my processing batch file on each set of images one at a time?
You may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:
#echo off
call :treeProcess
goto :eof
:treeProcess
rem Do whatever you want here over the files of this subdir, for example:
for %%f in (*.tif) do echo %%f
for /D %%d in (*) do (
cd %%d
call :treeProcess
cd ..
)
exit /b
Aacini's solution works but you can do it in one line:
for /R %%f in (*.tif) do echo "%%f"
Jack's solution work best for me but I need to do it for network UNC path (cifs/smb share) so a slight modification is needed:
for /R "\\mysrv\imgshr\somedir" %%f in (*.tif) do echo "%%f"
The original tip for this method is here
Posting here as it seems to be the most popular question about this case.
Here is an old gem I have finally managed to find back on the internet: sweep.exe. It executes the provided command in current directory and all subdirectories, simple as that.
Let's assume you have some program that process all files in a directory (but the use cases are really much broader than this):
:: For example, a file C:\Commands\processimages.cmd which contains:
FOR %%f IN (*.png) DO whatever
So, you want to run this program in current directory and all subdirectories:
:: Put sweep.exe in your PATH, you'll love it!
C:\ImagesDir> sweep C:\Commands\processimages.cmd
:: And if processimages.cmd is in your PATH too, the command becomes:
C:\ImagesDir> sweep processimages
Pros: You don't have to alter your original program to make it process subdirectories. You have the choice to process the subdirectories only if you want so. And this command is so straightforward and pleasant to use.
Con: Might fail with some commands (containing spaces, quotes, I don't know). See this thread for example.
I know this is not recursion (iteration through enumerated subdirectories?), but it may work better for some applications:
for /F "delims=" %%i in ('dir /ad /on /b /s') do (
pushd %%i
dir | find /i "Directory of"
popd
)
Replace the 3rd line with whatever command you may need.
dir /ad - list only directories
The cool thing is pushd does not need quotes if spaces in path.
rem Replace "baseline" with your directory name
for /R "baseline" %%a in (*) do (
echo %%a
)

Looking for a simple Batch script that modifies file name

I have a list of files in a folder that end with .swf.
I want to change all those files from X.swf to X<some number>.swf.
How can I do that?
This little script will change all *.swf files into the equivalent *_42.swf files.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f %%a in ('dir /b *.swf') do (
set fspec=%%a
set newfspec=!fspec:~0,-4!_42.swf
echo ren !fspec! !newfspec!
)
endlocal
Actually, as it stands now, it will just echo the commands that it wants to execute. Once you're happy they're correct, you can just remove the echo from that renaming line above.
It works by using for /f to get a list of all SWF files and then using string manipulation to:
remove the last four characters (the.swf extension); then
add a new _42.swf extension onto the end.
And, please, make sure you back them up first :-)
You could use the following one-liner directly from the command prompt:
FOR %F IN (*.swf) DO RENAME "%F" "%~nF123.*"
where 123 stands for your number of choice.
Alternatively you could create a batch file and take advantage of its ability to accept parameters. Use the following script:
#ECHO OFF
SET "suffix=%~1"
FOR %%F IN (*.swf) DO RENAME "%%F" "%%~nF%suffix%.*"
Now if the batch's name is renamer.bat, you can invoke it like this:
renamer.bat 2011
and it will add 2011 to the name of every .swf file in the current directory.
Assuming <X> in your description is supposed to be constant and you don't explicitly require a batch script to solve your problem, you can use Windows Explorer as mentioned in an article by Microsoft titled "Rename a file".
Here's a an extract from said article:
"You can also rename several files at one time, which is useful for grouping related items. To do this, select the files [then press F2]. Type one name, and then each of the files will be saved with the new name and a different sequential number at the end (for example, Renamed File (2), Renamed File (3), and so on)."

Resources