1.

Solve : Variables within variables?

Answer»

I am trying to develop a script that will turn the jumbled up mess of files I have in a folder into an organized folder with a set naming scheme. There are a lot of files, so doing this manually would take almost an entire two days of work, plus I'd really like to see if this can be done in batch anyway. The problem is coming from one line in the for command...

Code: [Select]@echo off
setlocal enabledelayedexpansion
cls

cd "C:\Users\User\desktop\Stuff\testbat"

for /f "delims=" %%F in ('dir /s /b *Form4*') do (
set OldName=%%~nF

echo !OldName!
set /p NameStart=Offset by ?
set /p NameLength=Characters Long?

set NewName=!OldName:~!NameStart!,!NameLength!!%%xF

echo !NewName!>>Namelog.txt
)

The error comes in on the set NewName line. I have tried using quotes around the two embedded variables, and I get the following in the txt file

OldName:~"7","11"%xF
OldName:~"0","13"%xF

I tried using the single quotes around the two variables and GOT the same only with single quotes around the numbers. I tried using double quotes around the entire string and got this

"Form4 Example1NameStartNameLength"%xF
"Example2 Form4NameStartNameLength"%xF

I even tried quotes on the inside of the exclamation points (i.e. !"OldName:~!NameStart!,!NameLength!"!%%xF) and I got this in the file

~7,11"%xF
~0,13"%xF

I even went so far as to try to export the Name inputs to other files and then try importing the data into the correct places (got rid of extra exclamation points, but cmd prompt kept erroring saying it could not find file specified, even though I hardcoded the file paths). Nothing seems to work.

Does anyone know how to get this to work? Or if it is even possible?You can do it, but you have to double up some of the exclamation marks/percent signs. I am about to leave for work but later today I shall post a WORKED out example.
Call Set might work in this instance. Try:

Code: [Select] call set NewName=%%OldName:~!NameStart!,!NameLength!%%%%~xF
Good luckQuote from: Dusty on September 16, 2011, 12:15:45 AM

Call Set might work in this instance.

Good suggestion
The call set worked great. Thank you. One more question, more in line with the for command. How do you "skip" within a for command? Example: I want the user to see what is being renamed and asked if they want to continue with the renaming process, if they do not, how do I skip that particular file, but keep the for command running. I've tried using labels and goto within the do, but they don't seem to work.Quote from: Raven19528 on September 16, 2011, 09:08:31 AM
How do you "skip" within a for command?

Ask for a user input e.g. y or n and then use an IF test, remembering to use delayed expansion.


@echo off
setlocal enabledelayedexpansion
cls
cd "c:\Users\User\desktop\Stuff\testbat"
for /f "delims=" %%F in ('dir /s /b *Form4*') do (
set OldName=%%~nF
echo Old file name : !OldName!
set /p NameStart="Offset from start ? "
set /p NameLength="Characters Long ? "
call set NewName=%%OldName:~!NameStart!,!NameLength!%%%%~xF
echo New file name : !NewName!
set /p DoRename="Rename [y/n] ? "
if /i "!DoRename!"=="y" (
echo Adding !NewName! to Namelog.txt
echo !NewName! >>Namelog.txt
) else (
echo Skipped
)
echo.
)


Quote from: Salmon Trout on September 16, 2011, 10:57:36 AM
Ask for a user input e.g. y or n and then use an IF test, remembering to use delayed expansion.


set /p DoRename="Rename [y/n] ? "
if /i "!DoRename!"=="y" (
echo Adding !NewName! to Namelog.txt
echo !NewName! >>Namelog.txt
) else (
echo Skipped
)



Explanation of above:

set /p DoRename="Rename [y/n] ? "

Ask if user wants to rename. Request y or n as input.

if /i "!DoRename!"=="y"

IF test. The /i switch makes it case insensitive, so that the test will be satisfied if the user types y or Y. Anything else at all will cause the test to be unsatisfied, for example YES, Yes, yes etc.

As with FOR, you can have a single line IF test such as:

if /i "!DoRename!"=="y" echo !NewName! >>Namelog.txt

or you can use parentheses to make multi line structures like this

if /i "!DoRename!"=="y" (
echo Writing to file!
echo !NewName! >>Namelog.txt
echo Finished writing to file
)


If you want to do one thing or things if the IF test is satisfied, and another thing or things if it is not, you can use ELSE like this:

if /i "!DoRename!"=="y" (
echo Writing to file!
echo !NewName! >>Namelog.txt
echo Finished writing to file
) else (
echo skipping file
echo !NewName! >>Skipped-Namelog.txt
)


Note that for ELSE to work, you need a closing parenthesis ")" and ELSE and an opening parenthesis "(" all on the same line as you see above.

Note also that whether in a loop or not, you MUST match opening and closing parentheses carefully!

Also note that you can do simple IF - ELSE stuff like this

if /i "!DoRename!"=="y" (echo You typed Y) else (echo You did not type Y)

A final point is that when you do an echo to a file like this it is a good habit to have a space before the > or >> redirection operators.

echo %something% >>file.txt

This is because if you don't you will get problems if the final character of %something% is a figure. This is to do with redirection of console streams.



I found a way of doing this without going through a lot of embedded if statements:

for /f "delims=" %%F in ('dir /s /b %tarstr%') do call :renamesubroutine %%F

This gets all of the files with the *tarstr* target string in the folder and passes them to the rename subroutine that holds all of the looping and error-checking that I want to have in my program. I will post it either here or in the Batch programs thread.Alright, so this is a lot, and I still haven't added my error-checking/correction coding into it at all, but it has the functionality that I am looking for. Thank you for all of the help with this one.

Code: [Select]@echo off
setlocal enabledelayedexpansion
title Renamer v1.1
mode con: cols=61 lines=15
set origdir=%~dp0
set numnam=0

call :targets
cls
call :startstring
cls
call :endstring
cls

:renaming
for /f "delims=" %%F in ('dir /s /b %tarstr%') do (
cls
set OldFilePathAndName=%%~dpnxF
set OldName=%%~nF
set OldFilePath=%%~pF
set Extension=%%~xF
set FileDate=%%~tF
echo !OldName!!Extension! in !OldFilePath!
echo.
set /p Continue=Edit this filename {y,n}
if /i "!Continue!"=="y" call :EditNameSubroutine

set NewName=!startstr!!NewName!!endstr!!Extension!

cls
echo.
echo !NewName!
echo.
echo Is this correct
set /p yn9={y,n}
if /i "!yn9!"=="y" (
echo !NewName! from !OldName!!Extension! >>%origdir%\Renamelog.txt
ren "!OldFilePathAndName!" "!NewName!"
set /a numnam=!numnam!+1
)
)

cls
echo You changed the name of !numnam! files
echo You can view the names that were changed
echo in the Renamelog.txt file located at
echo %origdir%
echo.
echo Thank you for using Renamer v1.1
echo.
ping 1.1.1.1 -n 1 -w 10000>nul
goto eof


:targets
:loop
cls
echo Is the directory path in the targetdirectory.txt file?
set /p yn1={y,n}
cls

if /i "%yn1%"=="y" (
set /p tardir=<targetdirectory.txt
) else (
echo Type full path of target directory
set /p tardir=
)
if exist %tardir% (
cd %tardir%
) else (
echo Target does not exist
echo Please try again
ping 1.1.1.1 -n:1 -w:3000>nul
goto loop
)

echo Is there a target string you want to enter?
set /p yn2={y,n}
if /i "%yn2%"=="y" (
echo.
echo Type target string for renaming
set /p tarstr=[Target]
set tarstr="*!tarstr!*"
goto addtarstrques
) else (
set tarstr=*
goto eof
)

:addstring
cls
set /p addstr=[Target]
set addstr="*%addstr%*"
set tarstr=%addstr% %tarstr%
echo Searching for strings: %tarstr%
:addtarstrques
cls
echo.
echo Is there an additional string you wish to look for?
set /p yn3={y,n}
if /i "%yn3%"=="y" goto addstring
goto eof


:startstring
:startloop
cls
echo Is there a standard starting string
echo to the naming convention?
set /p yn4={y,n}
if /i "%yn4%"=="y" (
cls
echo Enter standard start string
echo [Include an ending space if desired]
echo.
set /p startstr=
) else (
set startstr=
goto eof
)
echo The current start string is "%startstr%"
echo Is this okay?
set /p yn5={y,n}
if /i "%yn5%"=="n" (
set startstr=
goto startloop
)
goto eof


:endstring
cls
echo Is there a standard ending string to the naming convention?
set /p yn5={y,n}
if /i "%yn5%"=="n" (
set endstr=
goto eof
)
cls
echo Would you like the end string to
echo include the date the file was created
set /p DateEnd=[y,n]
cls
if /i "%DateEnd%"=="y" call :DateEndFormatting
cls
echo Would you like the end string to include
echo today's date
set /p yn6={y,n}
cls
echo Enter standard end string
echo [Include spaces if desired]
set /p origendstr=
if /i "%yn6%"=="y" call :DateTodayFormatting
if "%DateEnd%"=="y" set origendstr=%origendstr%[date created]
echo The current end string is "%origendstr%"
echo Is this okay?
set /p yn7={y,n}
if /i "%yn7%"=="n" (
set origendstr=
goto endstring
)
if /i "%DateEnd%"=="y" set origendstr=%origendstr:~0,-14%
goto eof


:DateEndFormatting
echo In what format would you like the
echo date to appear:
echo.
echo 1. dd Mmm yy
echo.
echo 2. yyyymmdd
echo.
echo 3. Mmm dd, yyyy
echo.
echo 4. mm/dd/yy
echo.
echo 5. More...
echo.
set /p DateEndForm=Selection {1-5}-
if "%DateEndForm%"=="5" goto more
goto dateendskip
:more
cls
echo 6. dd Mmm yyyy
echo.
echo 7. yy/mm/dd
echo.
echo 8. mm/dd/yyyy
echo.
echo 9. yymmdd
echo.
set /p DateEndForm=Selection {6-9}-
:dateendskip
goto eof


:DateTodayFormatting
echo In what format would you like the
echo date to appear:
echo.
echo 1. dd Mmm yy
echo.
echo 2. yyyymmdd
echo.
echo 3. Mmm dd, yyyy
echo.
echo 4. mm/dd/yy
echo.
echo 5. More...
echo.
set /p DateTodayForm=Selection {1-5}-
if "%DateTodayForm%"=="5" goto more
goto settodayform
:more
cls
echo 6. dd Mmm yyyy
echo.
echo 7. yy/mm/dd
echo.
echo 8. mm/dd/yyyy
echo.
echo 9. yymmdd
echo.
set /p DateTodayForm=Selection {6-9}-
:settodayform
if "%date:~4,2%"=="01" set todaymonth=Jan
if "%date:~4,2%"=="02" set todaymonth=Feb
if "%date:~4,2%"=="03" set todaymonth=Mar
if "%date:~4,2%"=="04" set todaymonth=Apr
if "%date:~4,2%"=="05" set todaymonth=May
if "%date:~4,2%"=="06" set todaymonth=Jun
if "%date:~4,2%"=="07" set todaymonth=Jul
if "%date:~4,2%"=="08" set todaymonth=Aug
if "%date:~4,2%"=="09" set todaymonth=Sep
if "%date:~4,2%"=="10" set todaymonth=Oct
if "%date:~4,2%"=="11" set todaymonth=Nov
if "%date:~4,2%"=="12" set todaymonth=Dec
if "%DateTodayForm%"=="1" set origendstr=%origendstr%%date:~7,2% %todaymonth% %date:~12%
if "%DateTodayForm%"=="2" set origendstr=%origendstr%%date:~10%%date:~4,2%%date:~7,2%
if "%DateTodayForm%"=="3" set origendstr=%origendstr%%todaymonth% %date:~7,2%, %date:~10%
if "%DateTodayForm%"=="4" set origendstr=%origendstr%%date:~4,6%%date:~12%
if "%DateTodayForm%"=="6" set origendstr=%origendstr%%date:~7,2% %todaymonth% %date:~10%
if "%DateTodayForm%"=="7" set origendstr=%origendstr%%date:~12%/%date:~4,5%
if "%DateTodayForm%"=="8" set origendstr=%origendstr%%date:~4%
if "%DateTodayForm%"=="9" set origendstr=%origendstr%%date:~12,2%%date:~4,2%%date:~7,2%
goto eof


:DateEndSet
if "!FileDate:~0,2!"=="01" set month=Jan
if "!FileDate:~0,2!"=="02" set month=Feb
if "!FileDate:~0,2!"=="03" set month=Mar
if "!FileDate:~0,2!"=="04" set month=Apr
if "!FileDate:~0,2!"=="05" set month=May
if "!FileDate:~0,2!"=="06" set month=Jun
if "!FileDate:~0,2!"=="07" set month=Jul
if "!FileDate:~0,2!"=="08" set month=Aug
if "!FileDate:~0,2!"=="09" set month=Sep
if "!FileDate:~0,2!"=="10" set month=Oct
if "!FileDate:~0,2!"=="11" set month=Nov
if "!FileDate:~0,2!"=="12" set month=Dec
if "%DateEndForm%"=="1" set endstr=%origendstr%!FileDate:~3,2! !month! !FileDate:~8,2!
if "%DateEndForm%"=="2" set endstr=%origendstr%!FileDate:~6,4!!FileDate:~0,2!!FileDate:~3,2!
if "%DateEndForm%"=="3" set endstr=%origendstr%!month! !FileDate:~3,2!, !FileDate:~6,2!
if "%DateEndForm%"=="4" set endstr=%origendstr%!FileDate:~0,6!!FileDate:~8,2!
if "%DateEndForm%"=="6" set endstr=%origendstr%!FileDate:~3,2! !month! !FileDate:~6,2!
if "%DateEndForm%"=="7" set endstr=%origendstr%!FileDate:~8,2!!FileDate:~0,5!
if "%DateEndForm%"=="8" set endstr=%origendstr%!FileDate:~0,10!
if "%DateEndForm%"=="9" set endstr=%origendstr%!FileDate:~8,2!!FileDate:~0,2!!FileDate:~3,2!
goto eof


:setcaps
set NewName=!NewName:A=a!
set NewName=!NewName:B=b!
set NewName=!NewName:C=c!
set NewName=!NewName:D=d!
set NewName=!NewName:E=e!
set NewName=!NewName:F=f!
set NewName=!NewName:G=g!
set NewName=!NewName:H=h!
set NewName=!NewName:I=i!
set NewName=!NewName:J=j!
set NewName=!NewName:K=k!
set NewName=!NewName:L=l!
set NewName=!NewName:M=m!
set NewName=!NewName:N=n!
set NewName=!NewName:O=o!
set NewName=!NewName:P=p!
set NewName=!NewName:Q=q!
set NewName=!NewName:R=r!
set NewName=!NewName:S=s!
set NewName=!NewName:T=t!
set NewName=!NewName:U=u!
set NewName=!NewName:V=v!
set NewName=!NewName:W=w!
set NewName=!NewName:X=x!
set NewName=!NewName:Y=y!
set NewName=!NewName:Z=z!
:caps
cls
echo !NewName!
echo.
set /p caps=How many capital letters?
if "!caps!"=="0" goto eof
for /l %%i in (1,1,!caps!) do (
cls
echo Capital Letter %%i
echo !NewName!
echo 012345678911111111112222222222333333333344444444445555555555
echo 01234567890123456789012345678901234567890123456789
set /p capoff=At Position-
set /a endcap=!capoff!+1
call set before=%%NewName:~0,!capoff!%%
call set capletter=%%NewName:~!capoff!,1%%
call set after=%%NewName:~!endcap!%%

set capletter=!capletter:a=A!
set capletter=!capletter:b=B!
set capletter=!capletter:c=C!
set capletter=!capletter:d=D!
set capletter=!capletter:e=E!
set capletter=!capletter:f=F!
set capletter=!capletter:g=G!
set capletter=!capletter:h=H!
set capletter=!capletter:i=I!
set capletter=!capletter:j=J!
set capletter=!capletter:k=K!
set capletter=!capletter:l=L!
set capletter=!capletter:m=M!
set capletter=!capletter:n=N!
set capletter=!capletter:o=O!
set capletter=!capletter:p=P!
set capletter=!capletter:q=Q!
set capletter=!capletter:r=R!
set capletter=!capletter:s=S!
set capletter=!capletter:t=T!
set capletter=!capletter:u=U!
set capletter=!capletter:v=V!
set capletter=!capletter:w=W!
set capletter=!capletter:x=X!
set capletter=!capletter:y=Y!
set capletter=!capletter:z=Z!

set NewName=!before!!capletter!!after!
)
cls
echo !NewName!
echo.
echo Are there any additional caps needed?
set /p yn14={y,n}
if /i "%yn14%"=="y" goto caps
goto eof


:EditNameSubroutine
:editname
cls
echo !OldName!
echo 012345678911111111112222222222333333333344444444445555555555
echo 01234567890123456789012345678901234567890123456789
echo.
set /p NameStart=Enter Start Position-
set /p NameEnd=Enter End Position-
set /a NameLength=1+!NameEnd!-!NameStart!

if /i "%DateEnd%"=="y" call :DateEndSet else set endstr=%origendstr%

call set NewName=%%OldName:~!NameStart!,!NameLength!%%

cls
echo !NewName!
echo Would you like to make changes to this part
echo {Start and end strings will be added later}
echo.
set /p yn10={y,n}
if /i "!yn10!"=="y" (
call :setcaps

cls
echo !NewName!
echo.
echo Would you like to insert anything into the name
set /p yn8={y,n}
if /i "!yn8!"=="y" call :insertsubroutine

cls
echo !NewName!
echo.
echo Would you like to remove anything from the name
set /p yn12={y,n}
if /i "!yn12!"=="y" call :removesubroutine
)
cls
echo !NewName!
echo.
echo Do you need to make any other changes?
echo.
set /p yn15={y,n}
if "%yn15%"=="y" goto editname
goto eof


:insertsubroutine
:insertsub
cls
echo !NewName!
echo 012345678911111111112222222222333333333344444444445555555555
echo 01234567890123456789012345678901234567890123456789
echo To the **right** of what position would
echo you like to insert the string?
set /p strpos=Right of Position-
echo What would you like to insert
set /p stradd=[String]
call set NewName=%%NewName:~0,!strpos!%%!stradd!%%NewName:~!strpos!%%
cls
echo !NewName!
echo.
echo Is there anything else that needs to be added
set /p yn11={y,n}
if /i "!yn11!"=="y" goto insertsub
goto eof


:removesubroutine
:removesub
cls
echo !NewName!
echo 012345678911111111112222222222333333333344444444445555555555
echo 01234567890123456789012345678901234567890123456789
echo What are the start and end positions
echo of the string to be removed?
echo.
echo Note that the start position should be
echo the last character that you want to stay
echo and the end position the last character
echo you want deleted
echo.
set /p remstpos=Start Position-
set /p remenpos=End Position-
call set NewName=%%NewName:~0,!remstpos!%%%%NewName:~!remenpos!%%
cls
echo !NewName!
echo.
echo Do you need to remove anything else
set /p yn13={y,n}
if /i "!yn13!"=="y" goto removesub


Discussion

No Comment Found