Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there a subroutine to convert a variable into uppercase?

1,230 views
Skip to first unread message

Timo Salmi

unread,
Dec 20, 2003, 2:38:07 AM12/20/03
to
DRAFT:

39} Is there a subroutine to convert a variable into uppercase?

As below. Note that the substitution method is case insensitive,
which means that while working for this application, it is not
useful for all character substitution tasks. Also note the minor
detail of the Scandinavian character conversion.

@echo off & setlocal enableextensions
set myvar_=My Test String åöä
call :ToUpcase "%myvar_%" myvar_
echo %myvar_%
endlocal & goto :EOF

:: ====================================================================
:ToUpcase
setlocal enableextensions
set var_=%1
set var_=%var_:a=A%
set var_=%var_:b=B%
set var_=%var_:c=C%
set var_=%var_:d=D%
set var_=%var_:e=E%
set var_=%var_:f=F%
set var_=%var_:g=G%
set var_=%var_:h=H%
set var_=%var_:i=I%
set var_=%var_:j=J%
set var_=%var_:k=K%
set var_=%var_:l=L%
set var_=%var_:m=M%
set var_=%var_:n=N%
set var_=%var_:o=O%
set var_=%var_:p=P%
set var_=%var_:q=Q%
set var_=%var_:r=R%
set var_=%var_:s=S%
set var_=%var_:t=T%
set var_=%var_:u=U%
set var_=%var_:v=V%
set var_=%var_:w=W%
set var_=%var_:x=X%
set var_=%var_:y=Y%
set var_=%var_:z=Z%
set var_=%var_:Ã¥=Ã…%
set var_=%var_:ä=Ä%
set var_=%var_:ö=Ö%
set var_=%var_:"=%
endlocal & set %2=%var_% & goto :EOF

The output is
F:\CMD>d:cmdfaq
MY TEST STRING ÅÖÄ

Another option is
@echo off & setlocal enableextensions
set myvar_=My Test String åöä
call :ToUpcase "%myvar_%" myvar_
echo %myvar_%
endlocal & goto :EOF

:: ====================================================================
:ToUpcase
:: Requires G(nu)AWK
setlocal enableextensions
gawk 'BEGIN{printf"@set var_=%%s\n",toupper(%1)}'>%temp%\tmp$$$.cmd
for %%c in (call del) do %%c %temp%\tmp$$$.cmd
endlocal & set %2=%var_% & goto :EOF

The output is slightly different
F:\CMD>d:cmdfaq
MY TEST STRING åöä

Using SED
@echo off & setlocal enableextensions
set myvar_=My Test String åöä
call :ToUpcase "%myvar_%" myvar_
echo %myvar_%
endlocal & goto :EOF

:: ====================================================================
:ToUpcase
:: Requires SED
setlocal enableextensions
echo @set var_=%1|sed "y/abcdefghijklmnopqrstuvwxyzåäö/ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ/"|sed -e "s/\"//g">%temp%\tmp$$$.cmd
for %%c in (call del) do %%c %temp%\tmp$$$.cmd
endlocal & set %2=%var_% & goto :EOF

The output is back to
F:\CMD>d:cmdfaq
MY TEST STRING ÅÖÄ

All the best, Timo

--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Useful script files and tricks ftp://garbo.uwasa.fi/pc/link/tscmd.zip

Phil Robyn

unread,
Dec 20, 2003, 3:54:19 AM12/20/03
to
Timo Salmi wrote:

> DRAFT:
>
> 39} Is there a subroutine to convert a variable into uppercase?
>

Hi, Timo,

Here are a couple of additional options; however, they don't handle
your special characters.

Batch file creates and invokes Java script:

<Win2000> c:\cmd>rlist demo\WSHtoUpper.cmd
=====begin c:\cmd\demo\WSHtoUpper.cmd ====================
1. @echo off
2. setlocal
3. echo var S1 = "%*"; > ~tmp.js
4. echo WScript.StdOut.WriteLine(S1.toUpperCase()); >>~tmp.js
5. for /f "tokens=*" %%a in ('cscript //nologo ~tmp.js') do set S1=%%a
6. endlocal & set %~n0=%S1%
=====end c:\cmd\demo\WSHtoUpper.cmd ====================

Batch file creates and invokes VBScript:

<Win2000> c:\cmd>rlist demo\WSHUpper.cmd
=====begin c:\cmd\demo\WSHUpper.cmd ====================
1. @echo off
2. setlocal
3. echo Wscript.Echo UCase("%*")>~tmp.vbs
4. for /f "tokens=*" %%a in ('cscript //nologo ~tmp.vbs') do set result=%%a
5. endlocal&set %~n0=%result%
=====end c:\cmd\demo\WSHUpper.cmd ====================

I am purposefully not deleting the '~tmp.*' files in case you want to examine
them (although they are very simple). Your practice of deleting them is
better and should be incorporated into any 'final' version.

--
Phil Robyn
Univ. of California, Berkeley

u n z i p m y a d d r e s s t o s e n d e - m a i l

Timo Salmi

unread,
Dec 20, 2003, 12:56:04 PM12/20/03
to
Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
> Timo Salmi wrote:
> > DRAFT:

> Here are a couple of additional options; however, they don't handle
> your special characters.

Thank you Phil. Even if I do not include JS and WBS in my particular
FAQ, they certainly are interesting options worth pointing out here.

Uno

unread,
Dec 20, 2003, 1:44:16 PM12/20/03
to

> 39} Is there a subroutine to convert a variable into uppercase?

Yes!

ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>uc.com
ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:J9u>>uc.com
ECHO:$+8\B$9}Q+$$5]6jv,tl(xD=8Q4qcOG6_L+:-M+fNI{n($*/9':leKcjt>>uc.com
ECHO:Gl]gxUURGHUS)$C;2j#>>uc.com
for /f %%a in ('echo %myvar% ^| uc.com') do set "myvar=%%a"
del uc.com


Uno

unread,
Dec 20, 2003, 2:44:53 PM12/20/03
to

> for /f %%a in ('echo %myvar% ^| uc.com') do set "myvar=%%a"I forgot

If the variable contains spaces I must add the tokens option:


ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>uc.com
ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:J9u>>uc.com
ECHO:$+8\B$9}Q+$$5]6jv,tl(xD=8Q4qcOG6_L+:-M+fNI{n($*/9':leKcjt>>uc.com
ECHO:Gl]gxUURGHUS)$C;2j#>>uc.com

for /f "tokens=*" %%a in ('echo %myvar% ^| uc.com') do set "myvar=%%a"
del uc.com


Phil Robyn

unread,
Dec 20, 2003, 3:15:33 PM12/20/03
to
Timo Salmi wrote:
> Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
>
>>Timo Salmi wrote:
>>
>>>DRAFT:
>
>
>>Here are a couple of additional options; however, they don't handle
>>your special characters.
>
>
> Thank you Phil. Even if I do not include JS and WBS in my particular
> FAQ, they certainly are interesting options worth pointing out here.
>
> All the best, Timo
>

The advantage of using Java Script or VB Script is that, unlike GAWK and SED,
Windows Scripting Host is already available.

To add another option, here is a batch file that invokes QBASIC to
convert a string to upper case, with the result returned in environment
variable QBUpper:

=====begin c:\cmd\demo\QBUpper.cmd ====================


1. @echo off
2. setlocal

3. echo OPEN "~ucout.$$$" FOR OUTPUT AS #1 >~tmp.bas
4. echo PRINT #1,UCASE$("%*")>>~tmp.bas
5. echo SYSTEM>>~tmp.bas
6. start /min /wait qbasic /run ~tmp.bas
7. for /f "tokens=*" %%a in ('type ~ucout.$$$') do set result=%%a
8. for %%a in (~tmp.bas ~ucout.$$$) do del %%a
9. endlocal & set %~n0=%result%
=====end c:\cmd\demo\QBUpper.cmd ====================

Uno

unread,
Dec 20, 2003, 3:37:22 PM12/20/03
to

> ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>uc.com
> ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:J9u>>uc.com
> ECHO:$+8\B$9}Q+$$5]6jv,tl(xD=8Q4qcOG6_L+:-M+fNI{n($*/9':leKcjt>>uc.com
> ECHO:Gl]gxUURGHUS)$C;2j#>>uc.com

Source:

100 MOV AH,3F
102 MOV BX,00
105 MOV CX,01
108 MOV DX,1000
10B INT 21
10D JB 012F
10F OR AX,AX
111 JZ 012F
113 CMP BYTE PTR [1000],61
118 JB 0126
11A CMP BYTE PTR [1000],7A
11F JA 0126
121 AND BYTE PTR [1000],DF
126 MOV AH,40
128 MOV BX,01
12B INT 21
12D JNB 0100
12F RET


Todd Vargo

unread,
Dec 20, 2003, 6:35:29 PM12/20/03
to

"Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
news:bs12o7$8fgvr$1...@ID-55492.news.uni-berlin.de...

Suppose the variable contains quotes.

One possible expansion could return the following command,
echo Wscript.Echo UCase(""LFN with spaces"")>~tmp.vbs

Of course, there is always the unbalanced quote possibility too.
echo Wscript.Echo UCase(""LFN with spaces")>~tmp.vbs

--
Todd Vargo (body of message must contain my name to reply by email)

Timo Salmi

unread,
Dec 21, 2003, 1:42:44 AM12/21/03
to
In article <4M0Fb.19548$wM.15...@news1.tin.it>, Uno <nos...@no.spam> wrote:
> > 39} Is there a subroutine to convert a variable into uppercase?
> ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>uc.com

Thank you, but you might know my (and that of some other regulars)
take on posted text binary utilities. While they can be interpreted
on-topic I consider them potentially too dangerous, and perhaps more
importantly quite uninformative from the FAQ point of view.
Furthermore, this one comes from an anonymous source, which in my
book always make them doubly suspect. Besides, from the FAQ point of
view, I ignore anonymous solution information.

Even the method below is much more useful, since it shows the source
code in Turbo Pascal (available for free on the net). That code ins
from
243286 Dec 19 2003 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
tsbat.zip Useful MS-DOS batch files and tricks, T.Salmi
which, while for MS-DOS+Win..95/98/Me has a lot of snippets which
are directly applicable on NT/2000/XP (like this one)

program upper;
var s : string;
i : byte;
f : text;
begin
if ParamCount > 0 then s := ParamStr(1) else s := '';
for i := 1 to Length(s) do s[i] := UpCase(s[i]);
Assign (f, 'tmp#$#$#.bat');
Rewrite (f);
writeln (f, '@echo off');
writeln (f, 'set upcase_=',s);
Close (f);
end.

Timo Salmi

unread,
Dec 21, 2003, 2:20:58 AM12/21/03
to
Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
> Timo Salmi wrote:
> > Thank you Phil. Even if I do not include JS and WBS in my particular
> > FAQ, they certainly are interesting options worth pointing out here.

> The advantage of using Java Script or VB Script is that, unlike GAWK and SED,


> Windows Scripting Host is already available.

I totally agree on that Phil. The reason why I do not include them
is mundane. I am not familiar enough with them. And while a FAQ of
course is always somewhat based on collective knowledge, the one I
am building is primarily based my own work and testing. Therefore it
is doubly important and useful that you posted those alternative
solutions here.

> To add another option, here is a batch file that invokes QBASIC to
> convert a string to upper case, with the result returned in environment
> variable QBUpper:

Yes. This option is covered also in

243286 Dec 19 2003 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
tsbat.zip Useful MS-DOS batch files and tricks, T.Salmi

where while for MS-DOS+Win..95/98/Me many tricks and solutions (but
not all) are directly applicable on the NT series. This is an
extract how I formulated it there:

.......
The program above can be written in an alternative way where the
QBASIC program is not echoed to the temporary file. The MS-DOS FIND
is used instead to build the auxiliary QBASIC program file. This
version of the trick was brought to my attention by Todd Vargo.
There are a couple of complications. The %1 parameter is not
directly available to the QBASIC program as in the echoing version.
Furthermore, it will be necessary to include the .BAT extension when
calling the batch.

@echo off
::
:: Check the input
if "%1"=="" goto _usage
echo %1 %2 %3> tmp###.bat
::
:: Build a QBASIC program to a file tmp$$$.bas
set skip=
find "'Q%skip%B" <%0 > tmp$$$.bas
goto _jump
OPEN "tmp###.bat" FOR INPUT AS #1 'QB
LINE INPUT #1, a$ 'QB
CLOSE #1 'QB
LET a$ = LTRIM$(RTRIM$(a$)) 'QB
LET b$ = "abcdefghijklmnopqrstuvwxyzедц" 'QB
LET c$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZЕДЦ" 'QB
FOR I = 1 TO LEN(a$) 'QB
LET J = INSTR(b$, MID$(a$, I, 1)) 'QB
IF J = 0 THEN 'QB
ELSE 'QB
MID$(a$, I, 1) = MID$(c$, J, 1) 'QB
END IF 'QB
NEXT I 'QB
OPEN "tmp###.bat" FOR OUTPUT AS #1 'QB
PRINT #1, "@echo off" 'QB
PRINT #1, "set upcase_=" ; a$ 'QB
CLOSE #1 'QB
SYSTEM 'QB
::
:: Run the QBASIC program
:_jump
qbasic /run tmp$$$.bas
::
:: Run the batch that sets the environment variables
call tmp###.bat
::
:: Show (test) results
echo upper_=%upcase_%
::
:: Clean up
for %%f in (tmp$$$.bas tmp###.bat) do if exist %%f del %%f
set upcase_=
goto _end
::
:: Error messages
:_usage
echo Usage %0 String1 [String2] [String3]
::
:: End
:_end

Timo Salmi

unread,
Dec 21, 2003, 2:36:04 AM12/21/03
to
Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
> Timo Salmi wrote:
> > Thank you Phil. Even if I do not include JS and WBS in my particular
> > FAQ, they certainly are interesting options worth pointing out here.

> To add another option, here is a batch file that invokes QBASIC to


> convert a string to upper case, with the result returned in environment

Phil, I have included Google pointers to your solutions.

Incidentally, when faced with the conversion task at large I most
often use an external program UPPER.EXE from
ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip myself.

Timo Salmi

unread,
Dec 21, 2003, 2:41:08 AM12/21/03
to
Todd Vargo <todd...@nccw.net> wrote:
> "Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
> > Timo Salmi wrote:
> > > DRAFT:
> > > 39} Is there a subroutine to convert a variable into uppercase?

> > 5. endlocal&set %~n0=%result%

> Suppose the variable contains quotes.

I stumbled on the same problem, and callously remove all the quotes
in the first of the FAQ solutions.

Phil Robyn

unread,
Dec 21, 2003, 3:00:14 AM12/21/03
to
Timo Salmi wrote:
<<<<major snip>>>>

> .......
> The program above can be written in an alternative way where the
> QBASIC program is not echoed to the temporary file. The MS-DOS FIND
> is used instead to build the auxiliary QBASIC program file. This
> version of the trick was brought to my attention by Todd Vargo.
> There are a couple of complications. The %1 parameter is not
> directly available to the QBASIC program as in the echoing version.
> Furthermore, it will be necessary to include the .BAT extension when
> calling the batch.
>

The %1...%9 parameters can be assigned to environment variables, which
then become available to QBASIC:

In the batch file:

set MYVAR=%1

In the QBASIC program:

YourString$ = ENVIRON$("MYVAR")

Uno

unread,
Dec 21, 2003, 5:52:05 AM12/21/03
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message news:bs3fd4$c...@poiju.uwasa.fi...


> In article <4M0Fb.19548$wM.15...@news1.tin.it>, Uno <nos...@no.spam> wrote:
> > > 39} Is there a subroutine to convert a variable into uppercase?
> > ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>uc.com
>
> Thank you, but you might know my (and that of some other regulars)
> take on posted text binary utilities. While they can be interpreted
> on-topic I consider them potentially too dangerous, and perhaps more
> importantly quite uninformative from the FAQ point of view.

OK,however the code I posted can be generated running the following debug script
and converting the resulting .com file with Laura Fairhead's command line tool
cm3.com ( http://lf.8k.com/TOOLS/TOOLS.HTM )

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
A 100
MOV AH,3F
MOV BX,00
MOV CX,01
MOV DX,1000
INT 21
JB 012F
OR AX,AX
JZ 012F


CMP BYTE PTR [1000],61

JB 0126


CMP BYTE PTR [1000],7A

JA 0126


AND BYTE PTR [1000],DF

MOV AH,40
MOV BX,01
INT 21
JNB 0100
RET
N CASE.COM
RCX
30
W
Q
:::::::::::::::::::::::::::::::::::::::::::::::::

Uno

unread,
Dec 21, 2003, 5:54:11 AM12/21/03
to
PS: uc.com can capitalize an entire text file:
type file.txt | uc.com > outfile.txt


Dr John Stockton

unread,
Dec 21, 2003, 9:58:46 AM12/21/03
to
JRS: In article <bs2ald$8oc84$1...@ID-55492.news.uni-berlin.de>, seen in
news:alt.msdos.batch.nt, Phil Robyn <zipp...@uclink.berkeley.edu>
posted at Sat, 20 Dec 2003 12:15:33 :-

>Timo Salmi wrote:
>> Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
>>>Here are a couple of additional options; however, they don't handle
>>>your special characters.
>>
>>
>> Thank you Phil. Even if I do not include JS and WBS in my particular
>> FAQ, they certainly are interesting options worth pointing out here.
>>
>> All the best, Timo
>>
>
>The advantage of using Java Script or VB Script is that, unlike GAWK and SED,
>Windows Scripting Host is already available.

Note that they already have active newsgroups, so substantial discussion
would be out of place in a Batch newsgroup, and should be redirected.

"Java Script" is non-existent. There is "Java" and there are
"javascript" & "Jscript", with the former being quite different to the
other pair (we should not quibble about capital letters, though IMHO
"Java" deserves one).

The method of invoking javascript and VBscript from a COMMAND/CMD batch
file is so on-topic that it ought to be in the misnomers section of any
FAQ (well, it's not frequently asked), with due allowance for 98-class &
NT-class systems.


Win98
=====

The following seems a convincing demonstration (bodged from Phil's
code) that Jscript can be run from a batch file in a Win98 DOS box
(which seems not widely known; cross-post therefore added) :-

C:\HOMEPAGE>type $.bat
@echo off
echo var S1 = "%* aaaa"; > ~tmp.js
echo WScript.Echo(S1.toUpperCase() + " " + new Date().toUTCString()); >>~tmp.js
cscript //nologo ~tmp.js


C:\HOMEPAGE>$
* AAAA Sun, 21 Dec 2003 14:27:43 UTC


That shows, in Win98 1st Edn, that the GMT/UTC date/time can at least
be displayed, by interpreted script from a batch file, in a Win98 DOS
box, though it would be nicer to run it when/where local time & GMT
differ ; the date format is that of Javascript and not directly given
AFAIK by VBscript.

The output of the cscript line can be redirected or piped, e.g. to STOW.

It is, therefore, possible to determine, by scripting, when Summer Time
starts/stops in a chosen year (and, if it does, the user's Hemisphere N/S)
and the nominal longitude; also the date of Easter etc.; and also to
display the civil date/time at any chosen location for which a TZ string
can be constructed.

Please set XP and/or FU if nature of response needs it.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://jibbering.com/faq/> Jim Ley's FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

Al Dunbar

unread,
Dec 21, 2003, 1:36:48 PM12/21/03
to

"Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
news:bs3juk$95fak$1...@ID-55492.news.uni-berlin.de...

> Timo Salmi wrote:
> <<<<major snip>>>>
> > .......
> > The program above can be written in an alternative way where the
> > QBASIC program is not echoed to the temporary file. The MS-DOS FIND
> > is used instead to build the auxiliary QBASIC program file. This
> > version of the trick was brought to my attention by Todd Vargo.
> > There are a couple of complications. The %1 parameter is not
> > directly available to the QBASIC program as in the echoing version.
> > Furthermore, it will be necessary to include the .BAT extension when
> > calling the batch.
> >
>
> The %1...%9 parameters can be assigned to environment variables, which
> then become available to QBASIC:
>
> In the batch file:
>
> set MYVAR=%1
>
> In the QBASIC program:
>
> YourString$ = ENVIRON$("MYVAR")

Even more than the first nine can be passed, something along these lines:

set /a argcount = 0
:loop
set arg=%1
if not defined arg goto:loopexit
set /a argcount += 1
set arg%argcount%=%arg%
shift
goto:loop
:loopexit

and in the QBASIC program:

numberofargs$ = environ$("argcount")
firstarg$ = environ$("arg1")

or, you could write a generalized routine that would create a string array
containing one arg per element.

/Al

Dr John Stockton

unread,
Dec 21, 2003, 2:22:15 PM12/21/03
to
JRS: In article <bs3ih4$d...@poiju.uwasa.fi>, seen in
news:alt.msdos.batch.nt, Timo Salmi <t...@UWasa.Fi> posted at Sun, 21 Dec
2003 09:36:04 :-

>Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
>> Timo Salmi wrote:
>> > Thank you Phil. Even if I do not include JS and WBS in my particular
>> > FAQ, they certainly are interesting options worth pointing out here.
>
>> To add another option, here is a batch file that invokes QBASIC to
>> convert a string to upper case, with the result returned in environment
>
>Phil, I have included Google pointers to your solutions.
>
>Incidentally, when faced with the conversion task at large I most
>often use an external program UPPER.EXE from
>ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip myself.

SUBS, via below, is more versatile; piping through

SUBS [az]-32

will suffice for many of us, but those writing French might like to add
such as 135=128 to deal with c-cedilla, etc.; not OS-dependent, though
affected by code page, so I may have the numbers wring for those in
France.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; Win98. ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

Dr John Stockton

unread,
Dec 21, 2003, 2:26:33 PM12/21/03
to
JRS: In article <bs3iqk$d...@poiju.uwasa.fi>, seen in

news:alt.msdos.batch.nt, Timo Salmi <t...@UWasa.Fi> posted at Sun, 21 Dec
2003 09:41:08 :-

>Todd Vargo <todd...@nccw.net> wrote:
>> "Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
>> > Timo Salmi wrote:
>> > > DRAFT:
>> > > 39} Is there a subroutine to convert a variable into uppercase?
>
>> > 5. endlocal&set %~n0=%result%
>
>> Suppose the variable contains quotes.
>
>I stumbled on the same problem, and callously remove all the quotes
>in the first of the FAQ solutions.

Since I don't recall seeing any Dutch persons here, you might get away
with converting quotes into florins (Æ’, with luck; #159) to hide them,
and converting back later.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.

Timo Salmi

unread,
Dec 22, 2003, 12:50:58 AM12/22/03
to
Al Dunbar <Alan-no-...@hotmail.com> wrote:
> "Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
> > Timo Salmi wrote:
> > <<<<major snip>>>>

> > The %1...%9 parameters can be assigned to environment variables, which


> > then become available to QBASIC:

> Even more than the first nine can be passed, something along these lines:


> set /a argcount = 0
> :loop
> set arg=%1
> if not defined arg goto:loopexit
> set /a argcount += 1
> set arg%argcount%=%arg%
> shift
> goto:loop
> :loopexit

DRAFT:

40) How do I get the number of arguments given to a script?

This task is not quite as trivial as it first appears to be. There
are a couple subtle pitfalls. Since the solution uses shift it
"destroys" the parameters from later usage, so they have to be
stored. The logic is that if one wants to count the parameters, one
is likely also to want to use the parameters! Also note the usage of
[] in the if testing lest there is confusion with parameters
potentially enclosed in quotes. If one needs a parameter count, it
is logical and sensible to always put it as the first thing into the
script. The denotations in the example below have clear UNIX
connotations.

@echo off & setlocal enableextensions enabledelayedexpansion
set /a argv=0
:_argvLoop
if [%1]==[] goto _exitArgvLoop
set /a argv+=1
set arg%argv%=%1
shift
goto _argvLoop
:_exitArgvLoop
::
:: Show the results
echo The number of parameters is %argv%
set /a count_=0
:_dispLoop
set /a count_+=1
if defined arg%count_% (echo !arg%count_%! & goto _dispLoop)
::
endlocal & goto :EOF

An example:
D:\TEST>cmdfaq one two "the third"
The number of parameters is 3
one
two
"the third"

Al Dunbar

unread,
Dec 22, 2003, 1:25:50 AM12/22/03
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message news:bs60o2$6...@poiju.uwasa.fi...

> Al Dunbar <Alan-no-...@hotmail.com> wrote:
> > "Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
> > > Timo Salmi wrote:
> > > <<<<major snip>>>>
>
> > > The %1...%9 parameters can be assigned to environment variables, which
> > > then become available to QBASIC:
>
> > Even more than the first nine can be passed, something along these
lines:
> > set /a argcount = 0
> > :loop
> > set arg=%1
> > if not defined arg goto:loopexit
> > set /a argcount += 1
> > set arg%argcount%=%arg%
> > shift
> > goto:loop
> > :loopexit
>
> DRAFT:
>
> 40) How do I get the number of arguments given to a script?
>
> This task is not quite as trivial as it first appears to be.

No, it is exactly as trivial as it appears to be. You are thinking about a
different task altogether.

> There
> are a couple subtle pitfalls. Since the solution uses shift it
> "destroys" the parameters from later usage, so they have to be
> stored.

But they are stored. %1 is stored in a variable called ARG1, %2 in ARG2 %77
in ARG77, and etc.

> The logic is that if one wants to count the parameters, one
> is likely also to want to use the parameters!

That is precisely why they are being put into a series of environment
variables just before running the QBasic program that is going to use them.
So they can be used.

If (as was not clear in the original post) there *is* a need for the batch
file to also process the parameters, the task of storing them in ARG1, ARG2,
and so on could be relegated to a secondary batch (or an internal one) that
is passed all of the originals as %*.

> Also note the usage of
> [] in the if testing lest there is confusion with parameters
> potentially enclosed in quotes.

That is why the parameters were assigned to an environment variable, and
their blankness tested with IF NOT DEFINED. Another reason I did that was to
avoid confusion with parameters that might happen to contain square
brackets.

> If one needs a parameter count, it
> is logical and sensible to always put it as the first thing into the
> script.

I called it argcount instead of argv, and it was also the first thing I put
in the script, as I happened to type the lines in the order you read them.
What exactly do you mean by "putting something as the first thing into the
script"?

/Al


Timo Salmi

unread,
Dec 22, 2003, 6:40:49 AM12/22/03
to
Al Dunbar <Alan-no-...@hotmail.com> wrote:
> "Timo Salmi" <t...@UWasa.Fi> wrote in message news:bs60o2$6...@poiju.uwasa.fi...
> > Al Dunbar <Alan-no-...@hotmail.com> wrote:

> > > if not defined arg goto:loopexit
> > > set /a argcount += 1
> > > set arg%argcount%=%arg%

> > DRAFT:


> > 40) How do I get the number of arguments given to a script?
> > This task is not quite as trivial as it first appears to be.

> No, it is exactly as trivial as it appears to be. You are thinking about a
> different task altogether.

I don't think the task quite as trivial even if the code is fairly
simple.

> > There
> > are a couple subtle pitfalls. Since the solution uses shift it
> > "destroys" the parameters from later usage, so they have to be
> > stored.

> But they are stored. %1 is stored in a variable called ARG1, %2 in ARG2 %77
> in ARG77, and etc.

Ah, now I see, Al. I am sorry! You migth have read my posting as
criticism of your solution. Most definitely not. Mine was drawing up
a new draft script FAQ item for a question that was not yet there
(even if I have had such in the my MS-DOS FAQ version for a long
time).

Yes, the parameteers are stored in our respective solutions. They
are not inherently stored, so one has to take care of it. That's why
the note it the FAQ.

> > The logic is that if one wants to count the parameters, one
> > is likely also to want to use the parameters!

> That is precisely why they are being put into a series of environment
> variables just before running the QBasic program that is going to use them.
> So they can be used.

Right on!

> > Also note the usage of
> > [] in the if testing lest there is confusion with parameters
> > potentially enclosed in quotes.

> That is why the parameters were assigned to an environment variable, and
> their blankness tested with IF NOT DEFINED. Another reason I did that was to
> avoid confusion with parameters that might happen to contain square
> brackets.

The "definied" trick is better than the one I used. Two further
comments on this detail. 1) I wrote the draft from scratch before
looking at yours. That's what I usually do, since I want to think
through the solutions by myself, whenever I am able. 2) It the
parameter contains [] it still wokrs. At least for the strings I
quickly tested when I was writing the snoppet.

> > If one needs a parameter count, it
> > is logical and sensible to always put it as the first thing into the
> > script.

> I called it argcount instead of argv, and it was also the first thing I put
> in the script, as I happened to type the lines in the order you read them.
> What exactly do you mean by "putting something as the first thing into the
> script"?

I mean this. In some programming situations there are intitial tasks
that should be done right away and store the results. Typically they
concern e.g. the parameters given. It is the same in say Turbo
Pascal, where the ParamCount(0) and ParamStr() variables are best
stored into separate varaible instad of recalleing them if needed
later in the code. This is because they may not be available later.

Matthias Tacke

unread,
Dec 22, 2003, 6:46:10 AM12/22/03
to
<Snip>
I reversed Al's idea doing the count in a called sub using the %*
Since the shift is in a sub it can be done in main again.
And with a for /L its quite straight forward.

@echo off & setlocal enableextensions

call :ArgCount %*
echo The number of parameters is %ArgC%
for /L %%A in (1,1,%ArgC%) do (echo/Arg%%A:%1 & shift)
endlocal & goto :EOF
:ArgCount
set /a ArgC=0
:_ArgCLoop
if [%1]==[] goto :EOF
set /a ArgC+=1
shift & goto _ArgCLoop

--
Greetings
Matthias________________________________________
For help on nt commands enter in a cmd window:
W2K>HH windows.chm::ntcmds.htm XP>HH ntcmds.chm

foxidrive

unread,
Dec 22, 2003, 9:24:15 AM12/22/03
to
On 22 Dec 2003 07:50:58 +0200, Timo Salmi wrote:

> Al Dunbar <Alan-no-...@hotmail.com> wrote:
>> "Phil Robyn" <zipp...@uclink.berkeley.edu> wrote in message
>>> Timo Salmi wrote:
>>> <<<<major snip>>>>
>
>>> The %1...%9 parameters can be assigned to environment variables, which
>>> then become available to QBASIC:
>
>> Even more than the first nine can be passed, something along these lines:
>> set /a argcount = 0
>> :loop
>> set arg=%1
>> if not defined arg goto:loopexit
>> set /a argcount += 1
>> set arg%argcount%=%arg%
>> shift
>> goto:loop
>> :loopexit
>
> DRAFT:
>
> 40) How do I get the number of arguments given to a script?
>
> This task is not quite as trivial as it first appears to be. There
> are a couple subtle pitfalls. Since the solution uses shift it
> "destroys" the parameters from later usage, so they have to be
> stored. The logic is that if one wants to count the parameters, one
> is likely also to want to use the parameters!

I had an idea about this topic so went on to develop it but almost busted a
kerfuffel valve due to the microsoft random error function.
Accordingly, this might not be the best way to do this, but here's what
worked in the end... any comments?

@echo off
setlocal enableextensions
for /f "delims=" %%a in ("%*") do call :countarg %%a
echo Number of items in the command line is %count%
echo The command line was %*
del temp.tmp
endlocal
goto :EOF

:countarg
set /a count=count+1
echo Command line item %count% is %1
shift
>temp.tmp echo -%1
for %%b in (temp.tmp) do if %%~zb GEQ 4 goto countarg


===[screen capture]===

c:\TEMP>c:\!XPBOX>test.bat 1 22 333 444 5 6 7 "8 8" 9 [] () + / \
Command line item 1 is 1
Command line item 2 is 22
Command line item 3 is 333
Command line item 4 is 444
Command line item 5 is 5
Command line item 6 is 6
Command line item 7 is 7
Command line item 8 is "8 8"
Command line item 9 is 9
Command line item 10 is []
Command line item 11 is ()
Command line item 12 is +
Command line item 13 is /
Command line item 14 is \
Number of items in the command line is 14
The command line was 1 22 333 444 5 6 7 "8 8" 9 [] () + / \

===[/screen capture]===

Matthias Tacke

unread,
Dec 22, 2003, 12:01:31 PM12/22/03
to
"Matthias Tacke" wrote:

><Snip>
>I reversed Al's idea doing the count in a called sub using the %*
>Since the shift is in a sub it can be done in main again.
>And with a for /L its quite straight forward.
>
>@echo off & setlocal enableextensions
>call :ArgCount %*
>echo The number of parameters is %ArgC%
>for /L %%A in (1,1,%ArgC%) do (echo/Arg%%A:%1 & shift)

It doesn't work any more :-( after some small changes. Don't know why.
I always get the first arg displayed.


>endlocal & goto :EOF
>:ArgCount
>set /a ArgC=0
>:_ArgCLoop
>if [%1]==[] goto :EOF
>set /a ArgC+=1
>shift & goto _ArgCLoop
>

This one is only a ligh modification of Timo's bu tit works.

@echo off & setlocal enableextensions enabledelayedexpansion
set /a argv=0 & call :ArgCount %*
:: Show the results
echo The number of parameters is %argv%
for /L %%A in (1,1,%argv%) do (echo/Arg%%A:!arg%%A!)


endlocal & goto :EOF
:ArgCount

if [%1]==[] goto :EOF

set /a argv+=1
set arg%argv%=%1
shift & goto ArgCount

Timo Salmi

unread,
Dec 22, 2003, 2:36:05 PM12/22/03
to
In article <bs6l81$a...@poiju.uwasa.fi>, Timo Salmi <t...@UWasa.Fi> wrote:
> Al Dunbar <Alan-no-...@hotmail.com> wrote:
> > > Also note the usage of
> > > [] in the if testing lest there is confusion with parameters
> > > potentially enclosed in quotes.

> > That is why the parameters were assigned to an environment variable, and
> > their blankness tested with IF NOT DEFINED. Another reason I did that was to
> > avoid confusion with parameters that might happen to contain square
> > brackets.

I have looked at this particular point a bit closer. I have not
(yet?) managed to come up with an example where the [] method would
fail in the code I posted. Perhaps someone else can.

@echo off & setlocal enableextensions enabledelayedexpansion
set /a argv=0
:_argvLoop
if [%1]==[] goto _exitArgvLoop
set /a argv+=1
set arg%argv%=%1
shift
goto _argvLoop
:_exitArgvLoop

Incidentally, looking back at my MS-DOS batch FAQ item on a similar
subject back from 6-Feb-2002 I note that I should have called argv
argc instead if Unix denotations are followed.

Al Dunbar

unread,
Dec 22, 2003, 9:06:13 PM12/22/03
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message
news:bs6l81$a...@poiju.uwasa.fi...

> Al Dunbar <Alan-no-...@hotmail.com> wrote:
> > "Timo Salmi" <t...@UWasa.Fi> wrote in message
news:bs60o2$6...@poiju.uwasa.fi...
> > > Al Dunbar <Alan-no-...@hotmail.com> wrote:
>
> > > > if not defined arg goto:loopexit
> > > > set /a argcount += 1
> > > > set arg%argcount%=%arg%
>
> > > DRAFT:
> > > 40) How do I get the number of arguments given to a script?
> > > This task is not quite as trivial as it first appears to be.
>
> > No, it is exactly as trivial as it appears to be. You are thinking about
a
> > different task altogether.
>
> I don't think the task quite as trivial even if the code is fairly
> simple.

As you finally realize below, we are talking about two similar, yet
different tasks.

> > > There
> > > are a couple subtle pitfalls. Since the solution uses shift it
> > > "destroys" the parameters from later usage, so they have to be
> > > stored.
>
> > But they are stored. %1 is stored in a variable called ARG1, %2 in ARG2
%77
> > in ARG77, and etc.
>
> Ah, now I see, Al. I am sorry! You migth have read my posting as
> criticism of your solution.

No. I just thought that it was making some reference to it...

> Most definitely not. Mine was drawing up
> a new draft script FAQ item for a question that was not yet there
> (even if I have had such in the my MS-DOS FAQ version for a long
> time).
>
> Yes, the parameteers are stored in our respective solutions. They
> are not inherently stored, so one has to take care of it. That's why
> the note it the FAQ.

And possibly also why it may be completely unimportant for the question of
the OP.

<snip>

> The "definied" trick is better than the one I used. Two further
> comments on this detail. 1) I wrote the draft from scratch before
> looking at yours. That's what I usually do, since I want to think
> through the solutions by myself, whenever I am able. 2) It the
> parameter contains [] it still wokrs. At least for the strings I
> quickly tested when I was writing the snoppet.


<snop> ;-)

> > > If one needs a parameter count, it
> > > is logical and sensible to always put it as the first thing into the
> > > script.
>
> > I called it argcount instead of argv, and it was also the first thing I
put
> > in the script, as I happened to type the lines in the order you read
them.
> > What exactly do you mean by "putting something as the first thing into
the
> > script"?
>
> I mean this.

Must be a language usage thing then, as, to me, it matters not the order
that things are put into the script, but the order in which they appear when
the script is complete. In fact, the second thing I put into a vbscript
source file being created to contain a function is the 'END FUNCTION'
statement. The first is the FUNCTION statement, and it often remains the
first executable statement. For any significant function, however, I find
that I am forced to add other statements in between those first two, such
that the 'END FUNCTION' statement remains the last one. But almost the first
one put into the script.

> In some programming situations there are intitial tasks
> that should be done right away and store the results.

Ahhh, not "put in the script", but "encountered in the script".

In fact, some of my scripts (actually in vbscript) studiously avoid doing
such things until they are actually needed. And when the time comes, the
results are saved for re-use the next time if there is the slightest chance
that the results might be different, or processing time could be saved.

> Typically they
> concern e.g. the parameters given. It is the same in say Turbo
> Pascal, where the ParamCount(0) and ParamStr() variables are best
> stored into separate varaible instad of recalleing them if needed
> later in the code. This is because they may not be available later.

And also because more work may be done to re-fetch them...

/Al


Al Dunbar

unread,
Dec 22, 2003, 9:06:25 PM12/22/03
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message
news:bs7h35$k...@poiju.uwasa.fi...

> In article <bs6l81$a...@poiju.uwasa.fi>, Timo Salmi <t...@UWasa.Fi> wrote:
> > Al Dunbar <Alan-no-...@hotmail.com> wrote:
> > > > Also note the usage of
> > > > [] in the if testing lest there is confusion with parameters
> > > > potentially enclosed in quotes.
>
> > > That is why the parameters were assigned to an environment variable,
and
> > > their blankness tested with IF NOT DEFINED. Another reason I did that
was to
> > > avoid confusion with parameters that might happen to contain square
> > > brackets.
>
> I have looked at this particular point a bit closer. I have not
> (yet?) managed to come up with an example where the [] method would
> fail in the code I posted. Perhaps someone else can.

Perhaps. I find it easier to avoid the possibility of an error like this in
the first place than to try to derive a proof that some potential solution
is safe under all possible circumstances.

>
> @echo off & setlocal enableextensions enabledelayedexpansion
> set /a argv=0
> :_argvLoop
> if [%1]==[] goto _exitArgvLoop
> set /a argv+=1
> set arg%argv%=%1
> shift
> goto _argvLoop
> :_exitArgvLoop
>
> Incidentally, looking back at my MS-DOS batch FAQ item on a similar
> subject back from 6-Feb-2002 I note that I should have called argv
> argc instead if Unix denotations are followed.

When I wrote my response, I initially made references to your ARGC variable,
and then noticed you didn't have one. I thought it would be too petty to
point that out. ;-)

/Al


Marty List

unread,
Dec 23, 2003, 9:07:08 AM12/23/03
to

"foxidrive" <foxi...@Shotmail.com> wrote in message
news:mfp2stsds99h$.1bl1uu29lmka0$.dlg@40tude.net...


I try to avoid temp files whenever possible, so I would do it like this:

@Echo Off


setlocal enableextensions
:: for /f "delims=" %%a in ("%*") do call :countarg %%a

:: This line from Matthias is simpler and seems to work just as well:
call :countarg %*


echo Number of items in the command line is %count%
echo The command line was %*

goto :EOF

:countarg
set /a count=count+1
echo Command line item %count% is %1
shift

set argv=%1
if defined argv goto :countarg
goto :EOF

foxidrive

unread,
Dec 23, 2003, 9:36:10 AM12/23/03
to
On Tue, 23 Dec 2003 07:07:08 -0700, Marty List wrote:

> I try to avoid temp files whenever possible, so I would do it like this:
>
> @Echo Off
> setlocal enableextensions
>:: for /f "delims=" %%a in ("%*") do call :countarg %%a
>:: This line from Matthias is simpler and seems to work just as well:
> call :countarg %*
> echo Number of items in the command line is %count%
> echo The command line was %*
> goto :EOF
>
>:countarg
> set /a count=count+1
> echo Command line item %count% is %1
> shift
> set argv=%1
> if defined argv goto :countarg
> goto :EOF


Thanks Marty. That's much better.

I also like Matthias' usage of call - it's neat.

Phil Robyn

unread,
Dec 23, 2003, 1:27:03 PM12/23/03
to

This is nice - but I noticed something curious when I invoked it with
the following arguments:

1 2 3 4 "abc def" 9087 () [] \ + / ?

Matthias Tacke

unread,
Dec 23, 2003, 3:05:22 PM12/23/03
to
Phil Robyn wrote:

>This is nice - but I noticed something curious when I invoked it with
>the following arguments:
>
>1 2 3 4 "abc def" 9087 () [] \ + / ?
>

Strange help screen Phil,
but the for loop has the same effect. If you reverse the last two args
or omit the question mark it doesn't happen.

It must be the shell ignoring any number of blanks between the slash
and the question mark passing this directly as "call /?" trashing all
other args.

Timo Salmi

unread,
Dec 23, 2003, 3:58:59 PM12/23/03
to
Phil Robyn <zipp...@uclink.berkeley.edu> wrote:
> This is nice - but I noticed something curious when I invoked it with
> the following arguments:
>
> 1 2 3 4 "abc def" 9087 () [] \ + / ?

It is good to have test cases. I tried that with the solution I
posted, and get (correctly)

D:\TEST>cmdfaq 1 2 3 4 "abc def" 9087 () [] \ + / ?
The number of parameters is 12


1
2
3
4
"abc def"
9087
()
[]
\
+
/
?

All the best, Timo

--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland

Timo's FAQ materials at http://www.uwasa.fi/~ts/http/tsfaq.html

Marco Maier Said

unread,
Jan 14, 2004, 5:06:11 AM1/14/04
to

> <Win2000> c:\cmd>rlist demo\WSHUpper.cmd
> =====begin c:\cmd\demo\WSHUpper.cmd ====================
> 1. @echo off
> 2. setlocal
> 3. echo Wscript.Echo UCase("%*")>~tmp.vbs
> 4. for /f "tokens=*" %%a in ('cscript //nologo ~tmp.vbs') do set result=%%a
> 5. endlocal&set %~n0=%result%

Or, to convert a file to uppercase:
>tmp.vbs echo Wscript.StdOut.Write Ucase(WScript.StdIn.ReadAll)
<infile.txt cscript /nologo tmp.vbs >outfile.txt

Pop

unread,
May 9, 2005, 6:33:21 AM5/9/05
to

"Marco Maier Said" <full...@softhome.net> wrote in message
news:7xpfybvrfp3t$.dlg@MRC.MIR.SID.75...

For batch, how about:

set src=c
set src2=c
set src3=C
call set src=%%src:%src2%=%src3%%%
set src
echo The original lower case c is now uppercase %SRC%
pause

I don't recall where I got it from, but it works in XP.

Pop


0 new messages