Page 1 of 1

%~z1 question

Posted: 02 Jul 2013 15:33
by Sponge Belly
Dear DosTips,

Please peruse the following snippet:

Code: Select all

if "%~1" neq "" (
if %~z1 equ 0 (
echo(file is empty
) else echo(file is not empty
) else echo(no cmdline args found


If a filename is supplied on the command line, all is well. But if no filename is specified, the program throws the “0 was unexpected at this time” error. What am I doing wrong? What is the workaround? :?:

Any help appreciated! :-)

- SB

Re: %~z1 question

Posted: 02 Jul 2013 16:04
by dbenham
Logically it looks like there should not be a problem. But the entire block of code is parsed at once - after normal variable expansion, but before any of the IF conditions are tested.

So if no argument is passed in, the parser sees the following erroneous IF statement on the 2nd line:

Code: Select all

if  equ 0

An obvious error :wink:

You can fix the problem by adding a character to both sides of the comparison. Another option is to use GOTO to skip code if no argument was passed in.

You never have those problems when using delayed expansion or FOR variables because the parser has finished parsing the IF statement before the delayed expansion or FOR variable expansion takes place.


Dave Benham

Re: %~z1 question

Posted: 02 Jul 2013 16:10
by Endoro
What you can try:

Code: Select all

@echo OFF &SETLOCAL
if "%~1" neq "" (
   if "%~z1" equ "0" (
      echo(file is empty
   ) else echo(file is not empty
) else echo(no cmdline args found
REM --------------------------------
SETLOCAL ENABLEDELAYEDEXPANSION
SET "z1=%~z1"
if "%~1" neq "" (
   if !z1! equ 0 (
      echo(file is empty
   ) else echo(file is not empty
) else echo(no cmdline args found

Re: %~z1 question

Posted: 05 Jul 2013 16:56
by Sponge Belly
@Endoro:

Thanks for the revised code! :-)

It never occurred to me that parameters could be referred to as “!~z1!” using delayed expansion. I don’t remember seeing it used before. I’ve seen “!%~1!”plenty of times, but that’s a whole other box of crayons. ;-)

@Dave:

Thanks for the great explanation. It makes perfect sense… except if what you say is true, then why does this snippet work?

Code: Select all

if "%~1" neq "" (if exist "%~1" (
for %%f in ("%~1") do (
if %%~zf equ 0 (echo(file is empty
) else echo(file is not empty)
) else echo(file "%~1" not found
) else echo(no cmdline args


Unlike the snippet in the OP, the plain for loop’s %%~zf var doesn’t cause an error when no cmdline arg is specified.

Please untangle this apparent contradiction for me.

Thanks! :-)

- SB

Re: %~z1 question

Posted: 05 Jul 2013 18:30
by Squashman
Sponge Belly wrote:It never occurred to me that parameters could be referred to as “!~z1!” using delayed expansion. I don’t remember seeing it used before. I’ve seen “!%~1!”plenty of times, but that’s a whole other box of crayons. ;-)

That is not what the code is doing. Reread the code.

Re: %~z1 question

Posted: 06 Jul 2013 00:49
by npocmaka_
There's one small issue with Endoro's code - if the file does not exists it will print that the file is empty :

try this:

Code: Select all

setlocal enabledelayedexpansion
set "empty="
if !empty! EQU 0 echo this will be printed
endlocal


I'd a similar problem here : http://ss64.org/viewtopic.php?id=1709 .And I've worked around this with one additional null (in cases without delayed expansion).
One more way to check if parameters are passed to the batch file is to use one additional variable (i don't know if it has any advantages or disadvantages).Here it is with additional variable and additional zero - just for example :

Code: Select all

@echo off
set "p1=%~1"
if not defined p1 (echo(no cmdline args found)
if defined p1 if not exist "%~f1" (echo(file does not exist)
if defined p1 if exist "%~f1" if %~z10 EQU 0 (echo(file is empty) else (echo(file is not empty)

Re: %~z1 question

Posted: 06 Jul 2013 05:48
by Sponge Belly
@npocmaka_:

Welcome to DosTips! :-)

@Squashman:

You’re absolutely right, as usual. :oops: I overlooked this line:

Code: Select all

SET "z1=%~z1"


Dave had said previously that one solution would be to use delayed expansion, so I made a link where there was none and confused !1z! in Endoro’s snippet with the erroneous !~z1!.

And that’s not all…

@Dave:

Dave Benham wrote:You never have those problems when using delayed expansion or FOR variables because the parser has finished parsing the IF statement before the delayed expansion or FOR variable expansion takes place.


Well, I was obviously on autopilot yesterday. :D I should really pay more attention. If people go to the trouble to answer my questions, the least I can do is take the time to read their answers properly.

All the same, the code in my previous post is a viable workaround for the undefined %~z1 problem.

- SB