Back in the MS-DOS epoch, the value of the PATH variable used
to be all upper case, at least when set using the PATH command.
In order to use this feature on another string, you had to save the PATH
to another temporary variable, then use the PATH command
to save the string to be converted in the PATH variable, copy the
value of the PATH variable back to the original variable, and restore the
PATH variable.
Though the PATH command in Windows NT 4 and later no
longer converts to upper case, we can still use this feature by calling
COMMAND.COM:
@ECHO OFF IF "%1"=="/C" GOTO COMMAND COMMAND /C %~s0 /C %* GOTO:EOF :COMMAND PATH %2 ECHO.%PATH%
This code may be compact, but to use the result in a variable would require additional code:
@ECHO OFF
IF "%1"=="/C" GOTO COMMAND
FOR /F "tokens=*" %%A IN ('COMMAND /C %~s0 /C %*') DO SET UpCase=%%A
GOTO:EOF
:COMMAND
PATH %2
ECHO.%PATH%
Still compact, but if you have to do some maintenace on this code, say, 3 years from now, will you still understand what it does? At first sight?
Personally, I prefer using the string substitution feature of Windows'
SET command, combined with
delayed variable expansion.
Besides conversion to upper case, this can be used just as easily to
convert to lower case:
SETLOCAL ENABLEDELAYEDEXPANSION SET String=Abc SET String CALL :UpCase String SET String CALL :LoCase String SET String ENDLOCAL GOTO:EOF :LoCase :: Subroutine to convert a variable VALUE to all lower case. :: The argument for this subroutine is the variable NAME. SET %~1=!%1:A=a! SET %~1=!%1:B=b! SET %~1=!%1:C=c! SET %~1=!%1:D=d! SET %~1=!%1:E=e! SET %~1=!%1:F=f! SET %~1=!%1:G=g! SET %~1=!%1:H=h! SET %~1=!%1:I=i! SET %~1=!%1:J=j! SET %~1=!%1:K=k! SET %~1=!%1:L=l! SET %~1=!%1:M=m! SET %~1=!%1:N=n! SET %~1=!%1:O=o! SET %~1=!%1:P=p! SET %~1=!%1:Q=q! SET %~1=!%1:R=r! SET %~1=!%1:S=s! SET %~1=!%1:T=t! SET %~1=!%1:U=u! SET %~1=!%1:V=v! SET %~1=!%1:W=w! SET %~1=!%1:X=x! SET %~1=!%1:Y=y! SET %~1=!%1:Z=z! GOTO:EOF :UpCase :: Subroutine to convert a variable VALUE to all upper case. :: The argument for this subroutine is the variable NAME. SET %~1=!%1:a=A! SET %~1=!%1:b=B! SET %~1=!%1:c=C! SET %~1=!%1:d=D! SET %~1=!%1:e=E! SET %~1=!%1:f=F! SET %~1=!%1:g=G! SET %~1=!%1:h=H! SET %~1=!%1:i=I! SET %~1=!%1:j=J! SET %~1=!%1:k=K! SET %~1=!%1:l=L! SET %~1=!%1:m=M! SET %~1=!%1:n=N! SET %~1=!%1:o=O! SET %~1=!%1:p=P! SET %~1=!%1:q=Q! SET %~1=!%1:r=R! SET %~1=!%1:s=S! SET %~1=!%1:t=T! SET %~1=!%1:u=U! SET %~1=!%1:v=V! SET %~1=!%1:w=W! SET %~1=!%1:x=X! SET %~1=!%1:y=Y! SET %~1=!%1:z=Z! GOTO:EOF
The code is not quite as compact as the code that uses the
PATH command, but it is much easier to read and maintain.
When run, the result of this sample batch code will look like this:
String=Abc String=ABC String=abc
Jiri sent me a clever adaptation of the UpCase
and LoCase routines, plus what he calls a Title Case
routine, also known as capitalization.
His code doesn't require delayed variable
expansion, but unless you have a huge screen it does require
some scrolling to read it...
![]()
@ECHO OFF
SET String=Hello, how are you ?
SET String
CALL :TCase String
SET String
CALL :UpCase String
SET String
CALL :LoCase String
SET String
GOTO:EOF
:LoCase
:: Subroutine to convert a variable VALUE to all lower case.
:: The argument for this subroutine is the variable NAME.
FOR %%i IN ("A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i" "J=j" "K=k" "L=l" "M=m" "N=n" "O=o" "P=p" "Q=q" "R=r" "S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z") DO CALL SET "%1=%%%1:%%~i%%"
GOTO:EOF
:UpCase
:: Subroutine to convert a variable VALUE to all UPPER CASE.
:: The argument for this subroutine is the variable NAME.
FOR %%i IN ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z") DO CALL SET "%1=%%%1:%%~i%%"
GOTO:EOF
:TCase
:: Subroutine to convert a variable VALUE to Title Case.
:: The argument for this subroutine is the variable NAME.
FOR %%i IN (" a= A" " b= B" " c= C" " d= D" " e= E" " f= F" " g= G" " h= H" " i= I" " j= J" " k= K" " l= L" " m= M" " n= N" " o= O" " p= P" " q= Q" " r= R" " s= S" " t= T" " u= U" " v= V" " w= W" " x= X" " y= Y" " z= Z") DO CALL SET "%1=%%%1:%%~i%%"
GOTO:EOF
This is what the result will look like:
String=Hello, how are you ? String=Hello, How Are You ? String=HELLO, HOW ARE YOU ? String=hello, how are you ?
Brian Williams sent me a script by Brad Thone, which uses a hitherto unknown feature of XP's SET command: string substitution is case-insensitive.
The (slightly modified) script is shown below:
@ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION SET _SAMPLE=Test Output to be Cased. CALL :UCase _SAMPLE _RESULTS ECHO.%_RESULTS% CALL :LCase _SAMPLE _RESULTS ECHO.%_RESULTS% ENDLOCAL GOTO:EOF :LCase :UCase :: Converts to upper/lower case variable contents :: Syntax: CALL :UCase _VAR1 _VAR2 :: Syntax: CALL :LCase _VAR1 _VAR2 :: _VAR1 = Variable NAME whose VALUE is to be converted to upper/lower case :: _VAR2 = NAME of variable to hold the converted value :: Note: Use variable NAMES in the CALL, not values (pass "by reference") SET _UCase=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z SET _LCase=a b c d e f g h i j k l m n o p q r s t u v w x y z SET _Lib_UCase_Tmp=!%1! IF /I "%0"==":UCase" SET _Abet=%_UCase% IF /I "%0"==":LCase" SET _Abet=%_LCase% FOR %%Z IN (%_Abet%) DO SET _Lib_UCase_Tmp=!_Lib_UCase_Tmp:%%Z=%%Z! SET %2=%_Lib_UCase_Tmp% GOTO:EOF
The resulting output looks like this:
TEST OUTPUT TO BE CASED. test output to be cased.
A completely different approach, by Mark Tattersall, uses the fact that FIND returns "file names" in upper case in its "File not found" message:
FOR /F "usebackq tokens=2 delims=-" %%A IN (`"FIND "" "lower case text" 2>&1"`) DO ECHO THIS IS NOT%%A
or, simplified (provided the text does not contain single quotes):
FOR /F "tokens=2 delims=-" %%A IN ('FIND "" "lower case text" 2ˆ>ˆ&1') DO ECHO THIS IS NOT%%A
This can be used to convert text to upper case only, there is no lower case equivalent (yet).
Replacing the hard coded sample text by a command line argument we get something like this:
FOR /F "tokens=2 delims=-" %%A IN ('FIND "" "%~1" 2ˆ>ˆ&1') DO SET UpCaseText=%%A
Additional code is required to remove the trailing space that is introduced by this method.
| Note: | This method has been tested in Windows XP only. |
Another unexpected approach, also by Mark Tattersall, uses DIR /L to convert strings to lower case:
FOR %%B IN ("LOWER CaSe") DO (
FOR /F "delims=~" %%A IN ('ECHO %%Bˆ> ~%%B ˆ& DIR /L /B ~%%B') DO (
ECHO this is in %%A
DEL /Q ~%%B
)
)
This can be used to convert text to lower case only, there is no upper case equivalent (yet).
Replacing the hard coded sample text by a command line argument we get something like this:
FOR %%B IN ("%~1") DO (
FOR /F "delims=~" %%A IN ('ECHO %%Bˆ> ~%%B ˆ& DIR /L /B ~%%B') DO (
SET LoCaseText=%%A
DEL /Q ~%%B
)
)
| Notes: | (1) | Write access to the current directory is required to create the temporary file. |
| (2) | The string must conform to all file name limitations. | |
| (3) | The code as shown here does not check if the temporary file exists, so you may need some additonal code to prevent accidental file deletion. |
| visitors can't be wrong... | page last uploaded: 15 March 2010, 21:20 |