%~z1 question

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Sponge Belly
Posts: 200
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

%~z1 question

#1 Post by Sponge Belly » 02 Jul 2013 15:33

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

dbenham
Expert
Posts: 2390
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: %~z1 question

#2 Post by dbenham » 02 Jul 2013 16:04

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

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: %~z1 question

#3 Post by Endoro » 02 Jul 2013 16:10

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

Sponge Belly
Posts: 200
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: %~z1 question

#4 Post by Sponge Belly » 05 Jul 2013 16:56

@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

Squashman
Expert
Posts: 4198
Joined: 23 Dec 2011 13:59

Re: %~z1 question

#5 Post by Squashman » 05 Jul 2013 18:30

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.

npocmaka_
Posts: 498
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: %~z1 question

#6 Post by npocmaka_ » 06 Jul 2013 00:49

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)

Sponge Belly
Posts: 200
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: %~z1 question

#7 Post by Sponge Belly » 06 Jul 2013 05:48

@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

Post Reply