#1 09 Dec 2018 16:55

Rekrul
Member
Registered: 17 Apr 2016
Posts: 20

Command outputs a number, I want it in a var. so I can use it in IF

I have a command line program that will output the resolution of an image file. The command to do this is;

identify -format "%w" FILENAME.JPG

That will display the width of the image. You can also include %h for the height, but right now I'm only concerned with the width.

I want to write a script that uses a loop to go through all the files in a directory and move them into sub directories based on their width. To do that, I need the width in a numeric variable. However, even though it looks like a variable, it's not. At least not as far as the script is concerned.

I tried sending the output to a file which would get overwritten each time the loop executes, but completely failed in trying to figure out how to read it back in to a variable. I tried;

set /a width=<temp.txt

Naturally that didn't work. I then tried;

set /p width=<temp.txt

Which is the exact example given on another site for reading the contents of a file into a variable, and naturally that didn't work either, because nothing related to variables ever works like I expect it to. I have this problem every time I try to use variables because variable handling in Windows scripts is completely counter intuitive and requires jumping through hoops to make them behave the way that logic tells you that they should.

Here is my non-working script. Well, part of it anyway, for further sorting, I'd need to do more loops checking each next largest size on the list.

for %%F in (*.jpg) do (
identify -format "%%w" %%F >temp.txt
set /a width=<temp.txt
if %width% gtr 640 move %%F 1280\
)

The output of the identify command is a printed string. I need to get the contents of that string into a numeric variable and then move the file into the specified directory if that value is greater than 640. If there's a way to pipe the output of the identify command into a variable, I have no idea how. I only know how to write it to a temporary file, but couldn't figure out how to read that into a numeric variable.

Offline

#2 09 Dec 2018 17:12

Aacini
Member
Registered: 05 Dec 2012
Posts: 143

Re: Command outputs a number, I want it in a var. so I can use it in IF

The standard way to execute a program and get its output is via FOR /F command.

After that, you don't need to get the number in a variable. You may directly use the FOR parameter.

for %%F in (*.jpg) do (
   for /F %%w in ('identify -format "%%w" %%F') do (
      if %%w gtr 640 move %%F 1280\
   )
)

Of course, you may get the value in a variable:

   set "width=%%w"

... and use it, but be aware that doing that requires Delayed Expansion (this is the counter intuitive part of using variables in Batch files).

Antonio

Offline

#3 11 Dec 2018 12:59

Rekrul
Member
Registered: 17 Apr 2016
Posts: 20

Re: Command outputs a number, I want it in a var. so I can use it in IF

Thank you, that worked great.

My only previous programming experience is with BASIC and some assembly on the C64, and sometimes I find batch scripting to be infuriatingly counter-intuitive. The whole Delayed Expansion still has me scratching my head why anyone would EVER want to use it. Or why it would be considered so important that it was made the default. Call me crazy but when I set a variable to something, I expect reading the variable to give that value/string. I mean, if you hit redial on your phone, do you expect it to dial the number you dialed an hour ago instead of the one you just dialed a few minutes ago?

A couple years ago, I wrote a script that would take downloaded files and run them through several steps, unpacking the archives, unpacking the second set of archives if necessary, renaming certain files, etc. As part of one of the steps it performs a search & replace on one of the variables. I looked up examples on the net, copied them EXACTLY and it failed. Looked up more examples, they failed. I forget exactly how I fixed it, but through experimentation, I discovered that I had to add an extra character, or maybe omit one, even though I could find no reference to doing this anywhere on the net. Looking at the script now, I have no idea which is the non-standard part.

I don't even understand why the errorlevel has to be checked in reverse order from highest to lowest. It has a specific value, why can't I just check for that specific value? Does this apply to all numeric variables or is the errorlevel the only one that's broken in this way?

Offline

#4 11 Dec 2018 19:21

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,018
Website

Re: Command outputs a number, I want it in a var. so I can use it in IF

These issues are all to do with providing compatibility with ancient versions of Windows and DOS.

Rekrul wrote:

I don't even understand why the errorlevel has to be checked in reverse order from highest to lowest. It has a specific value, why can't I just check for that specific value? Does this apply to all numeric variables or is the errorlevel the only one that's broken in this way?

This is explained on the IF page
https://ss64.com/nt/if.html#errorlevel

Offline

#5 12 Dec 2018 04:13

RG
Member
From: Minnesota
Registered: 18 Feb 2010
Posts: 346

Re: Command outputs a number, I want it in a var. so I can use it in IF

@Rekrul,
As Simon stated, this has to do with maintaining compatibility. If you follow this and other forums you will quickly see that this is probably the biggest source of confusion with bat files.

Perhaps it would be helpful if you think in terms of 'Load Time' behavior and 'Run Time' behavior. Most people can relate to 'Run Time' behavior... but 'Load Time' behavior is largely ignored by those new to bat files and therein lies the problem!

VERY IMPORTANT CONCEPT:  Bat files are loaded into memory a line at a time. In this context, a LINE is an entire parenthesized block and may be many lines that you see on the screen! I encourage you to write your own little bat file to experiment with this. It will help you in the future. This won't be the last time you encounter such a situation!


Windows Shell Scripting and InstallShield

Offline

#6 12 Dec 2018 17:05

Aacini
Member
Registered: 05 Dec 2012
Posts: 143

Re: Command outputs a number, I want it in a var. so I can use it in IF

The need for Delayed Expansion is not the only cause of confusion in Batch files. The nature of 'Load Time' (parse phase) vs 'Run Time' may cause other interesting/funny effects.  I remember a small example I wrote in order to exemplify the nature of %normal% expansion. Suppose you need to exchange the values of two variables. In any other programming language you need the aid of a third auxiliary variable that keep the value of one variable:

auxVar = varOne;  varOne = varTwo;  varTwo = auxVar;

This is not necessary in a Batch file:

set "varOne=%varTwo%"  &  set "varTwo=%varOne%"

I will not explain why this works. Just apply the rules of "parse phase" vs "run phase" and you'll see it...

Antonio

Offline

#7 24 Dec 2018 00:51

Rekrul
Member
Registered: 17 Apr 2016
Posts: 20

Re: Command outputs a number, I want it in a var. so I can use it in IF

RG wrote:

@Rekrul,
As Simon stated, this has to do with maintaining compatibility. If you follow this and other forums you will quickly see that this is probably the biggest source of confusion with bat files.

If Microsoft cares so much about compatibility that they continued to use a scripting syntax that runs counter to all common sense, how do you explain the decision to leave the Choice command out of NT/XP? Seems like that would be a pretty big compatibility breaker.

Full confession: I have an old system (most people would consider it ancient) that still has XP on it. Yes, I should get a newer system, but I don't have a lot of cash and I really don't want Windows 10 with its forced updates and pervasive spyware. Anyway, in order to use Choice in scripts, I had to download a version of it. This is the one I've been using;

https://sourceforge.net/projects/vbsmc/files/Resources/

It uses a slightly different syntax than the one included with later versions of Windows. I have to use;

choice /c1234 Please choose [1-4]: /n

But that doesn't work on Windows 10. When I gave such a script to a friend, the window instantly closed. Instead I had to use;

choice /c 1234 /m "Please choose [1-4]:" /n

Of course that doesn't work on XP and causes the window to instantly close.

So the only way I can make sure the script is compatible across all versions of Windows is to include my copy of the Choice command with it. Distributing an EXE file isn't the most desirable solution and probably violates someone's copyright. Including two different scripts and/or telling people to download their own copy of Choice.exe pretty much negates the whole point of making a script to simplify things for less knowledgeable users.

RG wrote:

Perhaps it would be helpful if you think in terms of 'Load Time' behavior and 'Run Time' behavior. Most people can relate to 'Run Time' behavior... but 'Load Time' behavior is largely ignored by those new to bat files and therein lies the problem!

Because it runs contrary to common sense. I learned BASIC on the C64, and many of the commands in batch files are relatively similar such that they're not too hard for me to understand, but variable behavior just runs contrary to everything I know about variables. If they had intentionally wanted to confuse new programmers, I don't think they could have come with a better way to do it.

RG wrote:

VERY IMPORTANT CONCEPT:  Bat files are loaded into memory a line at a time. In this context, a LINE is an entire parenthesized block and may be many lines that you see on the screen! I encourage you to write your own little bat file to experiment with this. It will help you in the future. This won't be the last time you encounter such a situation!

I don't think I'll ever get used to this. I was never an expert programmer. I know BASIC and a little 6502 assembly. It's ingrained in my mind that variables should contain whatever value they're set to.

Ignoring history, from a purely programming standpoint, does it really make sense that "Load Time" is the default behavior and "Run Time" is a special case that you have to manually force the script to use? Wouldn't it be more logical to have it the other way around? Among script programmers, is "Load Time" behavior considered more useful than "Run Time"?


Also, why do I get logged out of the forum after a set period of time? I came here, logged in, spent quite some time typing in my message and then when I went to preview it, it said I didn't have permission to do that, I was no longer logged in and my message was gone. I had to type the whole thing again from scratch, and it's damn lucky I copied the whole thing as a precaution before hitting Preview a second time because I was logged out AGAIN and it discarded my message! Other forums usually just ask you to login in such a case and preserve whatever you've entered.

Offline

#8 24 Dec 2018 18:04

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,018
Website

Re: Command outputs a number, I want it in a var. so I can use it in IF

Rekrul wrote:

Also, why do I get logged out of the forum after a set period of time? I came here, logged in, spent quite some time typing in my message and then when I went to preview it, it said I didn't have permission to do that, I was no longer logged in and my message was gone. I had to type the whole thing again from scratch, and it's damn lucky I copied the whole thing as a precaution before hitting Preview a second time because I was logged out AGAIN and it discarded my message! Other forums usually just ask you to login in such a case and preserve whatever you've entered.

I have also noticed this happen on occasion, I think the behaviour varies according to the web browser and whether or not it is set to remember your forum password. I havent figured out the exact good/bad combinations so maybe someone else can comment what works best?

There are some server side options, but I think those only affect when you are shown as 'online' and 'last visit day/time'

Offline

#9 26 Dec 2018 02:00

Rekrul
Member
Registered: 17 Apr 2016
Posts: 20

Re: Command outputs a number, I want it in a var. so I can use it in IF

Simon Sheppard wrote:

I have also noticed this happen on occasion, I think the behaviour varies according to the web browser and whether or not it is set to remember your forum password. I havent figured out the exact good/bad combinations so maybe someone else can comment what works best?

There are some server side options, but I think those only affect when you are shown as 'online' and 'last visit day/time'

I wouldn't mind having to log back in if the site just took me back to the login page and preserved whatever I'd typed. Then once I log back in, have it take me back to the message edit page with my message intact.

Since non-members can't can't even begin the posting process, the fact that someone is trying to post a message without being logged in should alert the site to the fact that the person IS a member and WAS previously logged in. Once it knows that, it should take steps to log them back in so that they can continue with whatever they were doing.

Offline

#10 26 Dec 2018 11:23

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,018
Website

Re: Command outputs a number, I want it in a var. so I can use it in IF

Rekrul wrote:
Simon Sheppard wrote:

I have also noticed this happen on occasion, I think the behaviour varies according to the web browser and whether or not it is set to remember your forum password. I havent figured out the exact good/bad combinations so maybe someone else can comment what works best?

There are some server side options, but I think those only affect when you are shown as 'online' and 'last visit day/time'

I wouldn't mind having to log back in if the site just took me back to the login page and preserved whatever I'd typed. Then once I log back in, have it take me back to the message edit page with my message intact.

Since non-members can't can't even begin the posting process, the fact that someone is trying to post a message without being logged in should alert the site to the fact that the person IS a member and WAS previously logged in. Once it knows that, it should take steps to log them back in so that they can continue with whatever they were doing.

Yes that would make a lot more sense, the developers of the forum software are working on a complete rewrite/upgrade (called Flarum) which will I think address this and a few other usability issues. It is currently in beta and Im expecting a full release towards the end of 2019.

Flarum does have a very different, more modern look and feel. Overall I think it looks very promising but like anything new I suspect people will either love it or hate it!

Offline

Board footer

Powered by FluxBB