Batch Script to Change folder names - problem with duplicate names

Hello,
I asked this question here: http://www.experts-exchange.com/Programming/Languages/Scripting/Shell/Batch/Q_23103040.html

I am currently using this batch script to rename folders within a directory to have the same name as the directory plus the last two digits from the folder to be renamed.
i.e. C:\Test\trial05 will become C:\Test\Test05

But then I realized that some of my folders to be renamed only have single digit numbers (e.g. 1, 2, 3, 4, etc)
is there a way to make this script just add the number from a counter starting at 01 to each renamed folder?

Also is there a way to insert a "_" between name and number in renamed folders (e.g. test_05 instead of test05)?



and I thought the code below worked, but it doesnt.

I get the following error message:
"a duplicate file name exists"
So basically it will only rename the first nine folders name_01 - name_09.

Is there a script that will rename my folder from C:\Test\trial01 will become C:\Test\Test_01? While still taking into considertion that sometimes they might be numbered with a single digit (i.e. C:\Test\trial1 will become C:\Test\Test01)?  Or do I need two scripts?

Thank you kindly,
MJ
@echo off
setlocal enabledelayedexpansion
 
REM The folder containing A, B, C, etc.
set root=C:\GISWORK\Landcoverprep
 
for /F "usebackq" %%G in (`dir "%root%" /A:D /B`) do (
 for /F "usebackq" %%H in (`dir "%root%\%%G" /A:D /B`) do (
  set newdir=%%H
  if not "!newdir:~-2,1!"=="0" (set newdir=%%G_0!newdir:~-1!) else (set newdir=%%G_!newdir:~-2!)
  ren "%root%\%%G\%%H" "!newdir!"
 )
)
pause

Open in new window

mgjustAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

SteveGTRCommented:
What should be done is there is a duplicate? Assign it an available number? Ignore it?
0
SteveGTRCommented:
The 1st question should read as:

"What should be done if there is a duplicate?"
0
mgjustAuthor Commented:
To my limited understanding of batch scripting there is no duplicate.
As xxx_1 or xxx_01 are not the same as xxx_11, correct?

Please advise.
Thanks,
MJ
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

SteveGTRCommented:
That is correct.
0
mgjustAuthor Commented:
Pardon me, but I don't believe I am on the same page with you when it comes to "duplicate."

Then given that my examples are not duplicates, how can the above script be fixed to work?

I tested it like this:
C:\Test\trial1  became C:\Test\Test_01
C:\Test\trial11 nothing changed begetting the error message: "a duplicate file name exists"

If trial1 and trial11 are not the same, why is there this message and how can it be overcome to rename all files, not just those numbered 01-09?

Thank you,
MJ
0
rettiseertCommented:
...

have you tried the comment I posted in your orignial question?
0
mgjustAuthor Commented:
Yes, I tried it and , you'll need to forgive me, is it a vbscript or is visual basic?
If its a vbscript its not doing anything.  If its visual basic I am afaid I don't know how to run that.
0
SteveGTRCommented:
I understand what you are talking about now. I've created a slightly more resilient and complicated batch file for you:
@echo off
 
setlocal 
 
REM The folder containing A, B, C, etc.
set root=C:\GISWORK\Landcoverprep
 
for /F "usebackq" %%G in (`dir "%root%" /A:D /B`) do (
 for /F "usebackq" %%H in (`dir "%root%\%%G" /A:D /B`) do call :PROCESS "%%H"
)
 
pause
 
goto :EOF
 
:PROCESS
 
set rootDir=%~1
set seq=
 
:NEXTCHAR
 
if "%rootDir%"=="" echo Error parsing %~0&goto :EOF
 
if /i "%rootDir:~-1,1%" LSS "0" goto :STOP
if /i "%rootDir:~-1,1%" GTR "9" goto :STOP
 
set seq=%rootDir:~-1,1%%seq%
set rootDir=%rootDir:~0,-1%
 
goto NEXTCHAR
 
:STOP
 
if not "%rootDir:~-1,1%"=="_" set rootDir=%rootDir%_
if /i 1%seq% LEQ 20 set seq=0%seq%
 
if "%rootDir%%seq%"=="~1" goto :EOF
if exist "%rootDir%%seq%" echo Can not rename %~1 to "%rootDir%%seq%". The directory already exists&goto :EOF
 
ren "%~1" "%rootDir%%seq%"
 
goto :EOF

Open in new window

0
SteveGTRCommented:
Did a code review and have corrected a bug where I meant to skip directories that had already been renamed. A couple of cosmetic changes as well:
@echo off
 
setlocal 
 
REM The folder containing A, B, C, etc.
set root=C:\GISWORK\Landcoverprep
 
for /F "usebackq" %%G in (`dir "%root%" /A:D /B`) do (
 for /F "usebackq" %%H in (`dir "%root%\%%G" /A:D /B`) do call :PROCESS "%%H"
)
 
pause
 
goto :EOF
 
:PROCESS
 
set rootDir=%~1
set seq=
 
:NEXTCHAR
 
if "%rootDir%"=="" echo Error parsing %~0&goto :EOF
 
if /i "%rootDir:~-1,1%" LSS "0" goto STOP
if /i "%rootDir:~-1,1%" GTR "9" goto STOP
 
set seq=%rootDir:~-1,1%%seq%
set rootDir=%rootDir:~0,-1%
 
goto NEXTCHAR
 
:STOP
 
if not "%rootDir:~-1,1%"=="_" set rootDir=%rootDir%_
if /i 1%seq% LEQ 20 set seq=0%seq%
 
if "%rootDir%%seq%"=="%~1" goto :EOF
if exist "%rootDir%%seq%" echo Can not rename %~1 to "%rootDir%%seq%". The directory already exists&goto :EOF
 
ren "%~1" "%rootDir%%seq%"
 
goto :EOF

Open in new window

0
mish33Commented:
However in dir Test files foo22 and bar22 will result in the same name Test_22,
so what do you want to do with duplicates?
0
SteveGTRCommented:
My processing will skip the file after generating an message.

I realized from the last comment made by mish33 that my code didn't use the parent's name. I modified the code to work as required:
@echo off
 
setlocal 
 
REM The folder containing A, B, C, etc.
set root=C:\GISWORK\Landcoverprep
 
for /F "usebackq" %%G in (`dir "%root%" /A:D /B`) do (
 for /F "usebackq" %%H in (`dir "%root%\%%G" /A:D /B`) do call :PROCESS "%%H" "%%G"
)
 
pause
 
goto :EOF
 
:PROCESS
 
set workDir=%~1
set seq=
 
:NEXTCHAR
 
if "%workDir%"=="" echo Error parsing %~0&goto :EOF
 
if /i "%workDir:~-1,1%" LSS "0" goto :STOP
if /i "%workDir:~-1,1%" GTR "9" goto :STOP
 
set seq=%workDir:~-1,1%%seq%
set workDir=%workDir:~0,-1%
 
goto NEXTCHAR
 
:STOP
 
if /i 1%seq% LEQ 20 set seq=0%seq%
 
set workDir=%~2_%seq%
 
if "%workDir%"=="~1" goto :EOF
if exist "%workDir%" echo Can not rename %~1 to %workDir%. The directory already exists&goto :EOF
 
ren "%~1" "%workDir%"
 
goto :EOF

Open in new window

0
mgjustAuthor Commented:
I just tested this last code and it did not do anything except generate the test below? I saved it as a .cmd file, this is correct, yes?

The system could not find the file specified.
The system could not find the file specified.
The system could not find the file specified.
The system could not find the file specified.
The system could not find the file specified.
The system could not find the file specified.

Please advise,
Thanks for the help,
MJ
0
SteveGTRCommented:
You can save it as .cmd. I saved it as .bat. Go ahead and try that. Also make sure to copy the code using cut and paste. When running the code use a cmd box.

I tested it on my local machine. Of course I changed the starting directory. Is the starting directory available?

Lastly, if that doesn't work, then rem out the @echo off at the top of the code and all the commands will echo out. You'll be able to see the commands that generated the error. Report back with this information and we'll go from there.
0
SteveGTRCommented:
Never mind that last post. I test the code out to actually do the rename command and saw the errors. I switch around the code a bit and this should do the trick:
@echo off
 
setlocal 
 
REM The folder containing A, B, C, etc.
set root=c:\temp\temp\test
 
pushd "%root%" 
 
for /F "tokens=*" %%a in ('dir /A:D /B 2^>NUL') do (
  pushd "%%a"
  for /F "tokens=*" %%b in ('dir /A:D /B 2^>NUL') do call :PROCESS "%%b" "%%a"
  popd
)
 
popd
 
pause
 
goto :EOF
 
:PROCESS
 
set workDir=%~1
set seq=
 
:NEXTCHAR
 
if "%workDir%"=="" echo Error parsing %~0&goto :EOF
 
if /i "%workDir:~-1,1%" LSS "0" goto STOP
if /i "%workDir:~-1,1%" GTR "9" goto STOP
 
set seq=%workDir:~-1,1%%seq%
set workDir=%workDir:~0,-1%
 
goto NEXTCHAR
 
:STOP
 
if /i 1%seq% LEQ 20 set seq=0%seq%
 
set workDir=%~2_%seq%
 
if "%workDir%"=="%~1" goto :EOF
if exist "%workDir%" echo Can not rename %~1 to %workDir%. The directory already exists&goto :EOF
 
ren "%~1" "%workDir%"
 
goto :EOF

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
peprCommented:
You may try the following Python script. Modify the last line with full or relative path to the directory. You may also want to use the code directly from your other Python script.
import os
import re
 
def renameSubdirsInside(root):
    # Create the absolute path from what was given, ensure that
    # it is a directory, and then get the name of the last subdir.
    root = os.path.abspath(root)
    assert os.path.isdir(root)
    dname = os.path.basename(root)
 
    # Compile the regular expression for recognizing numbered
    # subdirectories.
    rex = re.compile(r'^.*(\d+)$')
 
    # Build the list of tuples from numbered subdirectories.
    lst = []
    for name in os.listdir(root):
        fullname = os.path.join(root, name)
        if os.path.isdir(fullname):
            m = rex.match(name)
            if m:
                newname = dname + '_%02i' % int(m.group(1))
                lst.append( (name, newname) )
 
    # Now rename the original subdirectories to the new names.
    for oldname, newname in lst:
        os.rename(os.path.join(root, oldname), 
                  os.path.join(root, newname))   
 
 
if __name__=='__main__':
    renameSubdirsInside('x2')

Open in new window

0
mgjustAuthor Commented:
SteveGTR: Yes, this final installation worked as wanted. Thank you.

pepr: "use the code directly from your other Python script." Which script?

I tried the python script but nothing happened,  I changed:

 if __name__=='__main__':

to

if __name__=='C:\folder':

Given: C:\folder\testA\trial01with the wanted result --> C:\folder\testA\testA_01 or C:\folder\testB\testB_01 etc

Thank you kindly,
MJ
0
peprCommented:
... the directory should be entered as the argument of the final  call renameSubdirsInside(directory). You probably want to put the value of the command line parameter or the name of the directory obtained in some other way.

Well, it was just my guess that you want to rename the directory with the generated results of processing donut+landscape. It may not be the case. Anyway...

The commands

if __name__=='__main__':
    renameSubdirsInside('x2')

are the body of the script. The above is only definition of the function and some import of the ready-to-be used modules. The special name __name__ is filled by Python or by the name of the source file (without .py) if it was used as the module, or by the string '__main__' if the script was launched directly from command line. This way, the body below

if __name__=='__main__':

is executed only when the script is launched directly. This is usually used for writing the test of the above defined functionality.

Say, you store the script inside myRename.py. Then you can launch it directly from command line or you import myRename inside another script and call myRename.renameSubdirsInside(somedir)...


import myRename
import sys
...
 
myRename.renameSubdirsInside(sys.argv[1])  

Open in new window

0
mgjustAuthor Commented:
Thank you for the solutions.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.