epickmatt
epickmatt

Reputation: 75

Make variable all lower case in batch without call

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

Upvotes: 7

Views: 4822

Answers (4)

T3RR0R
T3RR0R

Reputation: 2951

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.

Upvotes: 6

lit
lit

Reputation: 16236

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

Upvotes: 2

ScriptKidd
ScriptKidd

Reputation: 841

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%

Upvotes: 1

npocmaka
npocmaka

Reputation: 57252

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.

Upvotes: 9

Related Questions