Reputation: 75
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
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
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
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
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