Make variable all lower case in batch without call

Viewed 1994

Here is a code I found to make a value lower case, but was curious how to do it without the CALL and just use a variable:

SET String=Hello, how are you ?
CALL :LoCase String
:LoCase
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
4 Answers

I'm not sure which call you want to avoid - the one in the for loop or calling the subroutine. But it is possible to ditch both with macro and delayedExpansion which will be executed much faster:

@echo off

set locase=for /L %%n in (1 1 2) do if %%n==2 ( for %%# in (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) do set "result=!result:%%#=%%#!") ELSE setlocal enableDelayedExpansion ^& set result=

set "string=SOme STrinG "
%locase%%string%

echo %result%

Also because of the way how replacement works in batch files you can just list the lower case letters - this will increase the performance also. Probably the code above is the fastest possible way to set string in lowercase only in batch file.

If you don't wish to use Call at all, convert the function to a macro. Here's a macro that can convert upper or lower

@ECHO OFF & Setlocal DISABLEDelayedExpansion
(Set \n=^^^
%=Do Not Modify=%
)
(Set LF=^


%=Do Not Modify=%)
 Set CASE=For %%n in (1 2) Do IF %%n==2 (%\n%
  Set "Switch=?"%\n%
  If not "[?]" == "[!Sub!]" (%\n%
   If "!String!" == "" Echo/No args Input. %%Case:?=!Switch!%%!String!!LF! !Usage!%\n%
   For /F "Tokens=1,2 Delims={}" %%G in ("!String!")Do If not "%%~H" == "" (%\n%
    Set "String=%%~H"%\n%
    Set "upper=!Switch:-u=!" ^& If Not "!upper!" == "!switch!" For %%x in (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) Do (Set "String=!String:%%x=%%x!")%\n%
    Set "lower=!Switch:-l=!" ^& If Not "!lower!" == "!switch!" For %%x in (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) Do (Set "String=!String:%%x=%%x!")%\n%
    Set "supress=!Switch:-s=!" ^& If "!supress!" == "!switch!" Echo/!String!%\n%
    Set "%%~G=!String!"%\n%
   ) Else Echo Missing Arg. %%Case:?=!Switch!%%{%%G}{%%H}!LF! !Usage!%\n%
  ) Else echo/Substring Switch required. %%Case:?=!Switch!%%!String!!LF! !Usage!%\n%
 ) Else Set String=
 Set "SUB=?"
 Set "Usage=Usage: %%CASE:?=[-U|-L]{-S}%%{ReturnVar}{Input String}"
Setlocal ENABLEDelayedExpansion
rem /* usage examples */
 Set /P "iString=String: "
rem /* convert upper */
 %CASE:?=-u%{string.upper}{!iString!}
rem /* convert lower; suppress output */
 %CASE:?=-l -s%{string.lower}{!iString!}
rem /* Demonstrate Macro error handling */
 %CASE:?=-l%
 %CASE%{string.noswitch}{!iString!}
 %CASE:?=-l%{String.false}
 Set string.

It is easy enough to use the ToLower() function in PowerShell. If you are on a supported Windows platform, PowerShell is available. It runs on Linux and Mac.

SET "STRING=Hello, how are you ?"
FOR /F "delims= eol=" %A IN ('powershell -NoLogo -NoProfile -Command "'%STRING%'.ToLower()"') DO (SET "STRING=%~A")
ECHO STRING is now === %STRING%

If this goes into a .bat file script, double the PERCENT character on the FOR loop variable.

SET "STRING=Hello, how are you ?"
FOR /F "delims= eol=" %%A IN ('powershell -NoLogo -NoProfile -Command "'%STRING%'.ToLower()"') DO (SET "STRING=%%~A")
ECHO STRING is now === %STRING%

It will process a string containing a QUOTATION MARK character.

C:\src\t>SET "STRING=Now Is ""The Time"
C:\src\t>FOR /F "delims= eol=" %A IN ('powershell -NoLogo -NoProfile -Command "'%STRING%'.ToLower()"') DO (SET "STRING2=%~A")
C:\src\t>(SET "STRING2=now is "the time" )
C:\src\t>SET STRING
STRING=Now Is ""The Time
STRING2=now is "the time

If the code is written in PowerShell, it could be:

$String = "Hello, how are you?".ToLower()
Write-Output $String

DIR /L works for all filenames, even Unicode like ÁCCÉNTS.

The macro $lower is defined by:

set ^"$lower=(dir/l/b/o-d "%TEMP%"^|"%ComSpec%" /v/c"set/plower=&echo(!lower!") 9^>\\?\"%TEMP%"\"

where DELAYEDEXPANSION must be DISABLED.


A demonstration script:

@echo off
chcp 65001 >nul
====SETLOCAL DisableDelayedExpansion EnableExtensions


set "PATH="
set "DPATH="
set "PATHEXT=;"
set ^"$lower=(dir/l/b/o-d "%TEMP%"^|"%ComSpec%" /v/c"set/plower=&echo(!lower!") 9^>\\?\"%TEMP%"\"


echo START: %time%
%$lower%"Hello, how are you"
%$lower%"I print a string (VALID FILENAME) in lower case"
%$lower%"ABCDEFGHIIJKLMNOPQRSTUVWXYZ"
%$lower%"GreekΘ&Áccents work"
%$lower%"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ"
%$lower%"µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİİIJĴĶĹĻĽĿŁŃŅŇʼnŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽ"
%$lower%"   SPA        CES "
%$lower%"EXCLAMS!!!"
%$lower%";SEMICOLONS all work"
%$lower%"SADLY ILLEGAL FILENAMES DON'T"
%$lower%"\/:*?<>|"
echo END: %time%
Related