| 1. |
Solve : Variable in FOR loop? |
|
Answer» Greetings. I am wanting to create a text file listing all the files in a DIRECTORY. A quick search on google provided myriad examples. The below for loop works fine. Note, I added the time stamp string in order to write the time stamp at the top of my file in my required format. FOR /r "C:\Documents and Settings\Administrator\My Documents\My Pictures" %%X IN (*.jpg) DO ( Try to debug your test batch with more ECHO statements. For example, use a simple ECHO of the variable befog and after you change it. Surprise! Delayed expansion ? A very "interesting" post from Geek. gsnidow, due to the way the Windows NT family command interpreter (which is not "DOS", by the way) processes variable expansion in FOR structures, to set and expand variables within a loop, you need to use "delayed expansion". You set it up in a batch file by including this line somewhere before the loop setlocal enabledelayedexpansion The case doesn't matter - upper or lower or a mixture of the two, all are OK. Mostly it's OK to put it right at the start after the @echo off line that starts most scripts. If you leave it out then you can't use delayed expansion variables of the !var! type Now, we come to how you use this feature within a loop, (in fact within any structure where multiple lines are enclosed in brackets) You assign (set) the variable in the normal way, by using the set command followed immediately by an equals sign and then the variable value: SET var=%%X Note that there are no exclamation marks ("exclamation points") in the above line. To read (expand) the variable within the loop you treat it like a normal variable, but with the difference that you use exclamation marks (!) and not percent signs (%): echo !var! >> c:\FileList.txt You can do all the usual variable processing stuff with such a variable. Note also that once the loop has finished (after the closing bracket of the loop) you can still access the variable but you use percent signs as normal. In the script you showed above, after the loop has finished, %var% will contain the last value that !var! held. This might be useful sometimes if you want to know the last item in a list or sequence. A point - using double colons :: as comment markers is unofficial, undocumented and unsupported, and will in certain situations (within a loop for example) break a script. Use REM or Rem or rem or ReM instead. Another point - writing ALL the commands in UPPER CASE is not compulsory. Thank you so much Geek and Salmon for the very helpful points. I have made it easier on myself by creating c:\test, and putting only 3 files in it, Test1.txt..Test3.txt. At Geek's suggestion, I have been working on only the problem part, which, with my new test folder, boils down to... FOR /r "C:\test" %X IN (*.txt) DO SET var = %X Note I am not trying to do this in a batch file now, because I want to see what is happening in the cmd window. As expected, the output of this line is... C:\...>SET var = C:\test\Test1.txt C:\...>SET var = C:\test\Test2.txt C:\...>SET var = C:\test\Test3.txt This RESULT seems to me to imply that for each iteration of the loop, it is correctly assigning the value of the current file name to the var variable. I then tried this... FOR /r "C:\test" %X IN (*.txt) DO SET var = %X ECHO %var My thought was that since, based on my assumption above, the variable is being correctly set, the next step would be to ECHO it. However, this is not the case, as the output is now... C:\...>SET var = C:\test\Test1.txt ECHO %var C:\...>SET var = C:\test\Test2.txt ECHO %var C:\...>SET var = C:\test\Test3.txt ECHO %var It seems that it is only appending "ECHO %var" to the variable value, along with the file name of the current iteration. I am thinking it must be possible to carry out multiple actions in the DO part of the loop, but I can't seem to get it. One question to the delayed execution: I am having trouble understanding why it is necessary if, based on my first results, it seems to be correctly assigning the variable value without it. @Salmon - I'm going to continue to mess with it before I simply copy and paste your line of code, so I will probably have some more questions later. As for the all caps, I'm a SQL guy, and my practice is to always put key words in all caps, because it makes the code easier to read. Once again, I very much appreciate both of your helping me as I muddle through being a newbie at this. Thank you so much. Greg Quote FOR /r "C:\test" %X IN (*.txt) DO SET var = %X ECHO %var 1. You can't do this. 2. Variables have a percent sign before and after so %var won't work. 3. Quote As expected, the output of this line is... It was just echoing "set var = " (which is wrong; lose those spaces) and expanding %X. The variable %var% was not being set correctly. Trust me. Quote It was just echoing "set var = " (which is wrong; lose those spaces) and expanding %X. The variable %var% was not being set correctly. Trust me. Ah ha, those darned spaces. All seems to be good now, so I very much appreciate the help. One last question, how do I know when to use '%' and when to use '!' to wrap my variables? Thanks again. GregQuote from: gsnidow on May 23, 2011, 05:51:16 AM how do I know when to use '%' and when to use '!' to wrap my variables? Thanks again. You use % all the time except when you want to expand a variable, in a loop or other parenthetical structure (e.g. a long form IF), which you have previously set in that structure. @Salmon - I apologize if this is a newbie question, but I don't know what you mean by expanding a variable. I read some stuff on google, but most of it was dealing with posters having issues with expanding their variables in various languages. Could you possibly put it in laymen terms? Thanks. GregWhole waiting or Salmon Trout, here is some more reading. http://www.robvanderwoude.com/variableexpansion.phpQuote from: gsnidow on May 23, 2011, 08:14:40 PM I don't know what you mean by expanding a variable. Could you possibly put it in laymen terms? OK here GOES... You create a variable with the SET command, and when you use it in a statement, it gets "expanded" by the command interpreter cmd.exe. set animal=cat The command interpreter reserves some memory space for a variable called "animal" and stores the THREE characters 'cat' in that space. later you have echo %animal% When the command interpreter processes this line it identifies the variable because of the percent signs and looks up the value of "animal" in its list of variables. It finds 'cat' so it replaces %animal% with cat and executes echo cat This process of replacing a variable's name with the value it holds is called "expansion". Thanks for the help and explanation guys. That is a great article, and it does not seem so strange now. I very much appreciate you taking time out of your busy days to consider and respond to my questions. Greg |
|