0

How do i get different vars changed in a for loop with every run?

assume:

for %%i in ( 
              VAR:RUN1,RUN2,RUN3,RUN4,RUN5,RUN6,RUN7,RUN8,RUN9
             var1:1,2,3,4,5,6,7,8,9 
             var2:10,20,30,40,50,60,70,80,90 
             var3:a,b,c,d,e,f,g,h,i 
             var4:x,y,x,y,x,y,x,y,x 
                                                ) do (

echo %var1% %var2% %var3% %var4% 

)

while there are e.g. 9 different values of each var?

or to order the vars better way:

for %%i in ( 
          LoopRUN:VAR1,VAR2,VAR3,VAR4
             run1:1,10,a,x 
             run2:2,20,b,y
             run3:3,30,c,x 
             run4:4,40,d,y 
             run5:5,50,e,x 
             run6:6,60,f,y 
             run7:7,70,g,x 
             run8:8,80,h,y 
             run9:9,90,i,x 
                                                ) do (

echo %var1% %var2% %var3% %var4% 

)

This should result in something like this:

       C:\>1,10,a,x 
       2,20,b,y
       3,30,c,x 
       4,40,d,y 
       5,50,e,x 
       6,60,f,y 
       7,70,g,x 
       8,80,h,y 
       9,90,i,x 

EDIT:

I can't see how to get the correspondense clearly between the vars and calls.

It is a bit more difficult, instead of "echo" there is a call in each run/loop likewise:

"command /S %VAR1% -subswitch %VAR2% /H %VAR3% -o %VAR4%"

EXPLANATION:

With choosen solution it is possible to use REM lines to keep runs overview-able likewise:

REM Devicegroup A
run1
run2
run3
REM Devicegroup B
run4
run5
REM

Even if one forgets to set one VAR this is handled by code, the only problem will be if you use "run[x]..." a second time so keep an eye on your run-numbering!

While runs are done in not natural order, don't know if we could catch this. See Output:

command /S 10 -subswitch 10 /H a -o x
command /S 11 -subswitch 10 /H a -o x
command /S 12 -subswitch 20 /H b -o y
command /S 13 -subswitch 30 /H c -o x
command /S 14 -subswitch 40 /H d -o y
command /S 15 -subswitch 50 /H e -o x
ERROR: Missing variable in run[16]
command /S 17 -subswitch 70 /H g -o x
command /S 18 -subswitch 80 /H h -o y
command /S 19 -subswitch 90 /H i -o x
command /S 1 -subswitch 10 /H a -o x
command /S 20 -subswitch 20 /H b -o y
command /S 2 -subswitch 20 /H b -o y
command /S 3 -subswitch 30 /H c -o x
command /S 4 -subswitch 40 /H d -o y
command /S 5 -subswitch 50 /H e -o x
ERROR: Missing variable in run[6]
command /S 7 -subswitch 70 /H g -o x
command /S 8 -subswitch 80 /H h -o y
command /S 9 -subswitch 90 /H i -o x
peet
  • 274
  • 3
  • 5
  • 18
  • please show the `array` in your code. – Endoro Dec 12 '13 at 22:57
  • 3
    You'd need to say what exactly you want to do. Fixing code that doesn't do something you haven't specified is a guessing game. – Magoo Dec 12 '13 at 22:58
  • @Endoro there are 9 of them to be precise :) – peet Dec 12 '13 at 23:39
  • @Magoo I need to send a command with 4 different vars a lot of times and each time with different values for each var. – peet Dec 12 '13 at 23:39
  • @Endoro or 4 depending on which way to arrange the 9x4 or 4x9 vars. while i would prefer to go 9 times 4 vars. – peet Dec 13 '13 at 00:03
  • Am I correct in assuming that you are trying to extract the four values in each set into four separate variables? – unclemeat Dec 13 '13 at 00:38
  • @unclemeat you are right i added a better example in my question. – peet Dec 13 '13 at 01:09
  • 1
    Note that `run 9 times with 4 variables` is _entirely different_ than `run 4 times with 9 variables`: "there are 9 arrays... or 4 depending on which way to arrange the 9x4 or 4x9 vars. while i would prefer to go 9 times 4 vars" (?) – Aacini Dec 13 '13 at 03:27
  • @Aacini I totally agree. I need 9 calls in the example and maybe 14 calls tomorrow, the amount of calls corresponds to an amount of devices. Because of this i like the 9 times 4 way - while it should keep readable Array Definition for other collegues. – peet Dec 13 '13 at 07:04

4 Answers4

2
@ECHO OFF
SETLOCAL
for %%r in (  "run1:1,10,a,x",
             "run2:2,20,b,y",
             "run3:3,30,c,x",
             "run4:4,40,d,y",
             "run5:5,50,e,x",
             "run6:6,60,f,y",
             "run7:7,70,g,x",
             "run8:8,80,h,y",
             "run9:9,90,i,x"
 ) DO (
 for /f "tokens=2delims=:" %%i in ("%%~r") do (
  echo %%i
 )
)
GOTO :EOF

should produce the output you've asked for.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • haha, beat you to pretty much the same answer, except you haven't extracted the four values into separate variables. why have you included `"run1:"` `"run2:"` etc? – unclemeat Dec 13 '13 at 00:34
  • 1
    @unclemeat yes - saw your post & checked for similarity. Still no clear idea of how flexible the data format is, whether it actually comes from a file, whether 4 variables need to be set or whether a subroutine will be called with the comma-separated strings as parameters. Decided to produced precisely what was asked - but had the identical technique written onto my clipboard, so - publish and be damned as they say... :) – Magoo Dec 13 '13 at 00:45
  • Fair enough. Though it's fairly unclear, I decided he was probably looking to have them in separate variables, due to the line in his question - `echo %var1% %var2% %var3% %var4%`. – unclemeat Dec 13 '13 at 00:49
  • do i get you two right, that in unclemeat's example the vars get ordered only by seperator "," while in your first by line and then by ":" ? – peet Dec 13 '13 at 01:08
  • @peet Given your latest edit, use unclemeat's version and replace the `echo %%A...` with `command /S %%A -subswitch %%B /H %%C -o %%D` – Magoo Dec 13 '13 at 01:13
2

Another one!

@echo off
setlocal EnableDelayedExpansion
set LF=^


rem ** Previous two empty lines required
set "vars=1,10,a,x;2,20,b,y;3,30,c,x;4,40,d,y;5,50,e,x;6,60,f,y;7,70,g,x;8,80,h,y;9,90,i,x"
for /F "tokens=1-4 delims=," %%A in ("%vars:;=!LF!%") do echo command /S %%A -subswitch %%B /H %%C -o %%D

Output:

command /S 1 -subswitch 10 /H a -o x
command /S 2 -subswitch 20 /H b -o y
command /S 3 -subswitch 30 /H c -o x
command /S 4 -subswitch 40 /H d -o y
command /S 5 -subswitch 50 /H e -o x
command /S 6 -subswitch 60 /H f -o y
command /S 7 -subswitch 70 /H g -o x
command /S 8 -subswitch 80 /H h -o y
command /S 9 -subswitch 90 /H i -o x

EDIT: New method added as response to comments

Previous Batch file is the simplest way to solve this problem. However, if your concern is to "keep readable Array Definition for other collegues", then the method below may be clearer. This program also addresses your concern about "include a test, who check if you really have 4 vars":

@echo off
setlocal

rem Define the *array* of variables per run
set run[1]=1,10,a,x
set run[2]=2,20,b,y
set run[3]=3,30,c,x
set run[4]=4,40,d,y
set run[5]=5,50,e,x
set run[6]=6,60,f
set run[7]=7,70,g,x
set run[8]=8,80,h,y
set run[9]=9,90,i,x

for /F "tokens=1-5 delims==," %%A in ('set run[') do (
   if "%%E" neq "" (
      ECHO command /S %%B -subswitch %%C /H %%D -o %%E
   ) else (
      echo ERROR: Missing variable in %%A
   )
)

Output:

command /S 1 -subswitch 10 /H a -o x
command /S 2 -subswitch 20 /H b -o y
command /S 3 -subswitch 30 /H c -o x
command /S 4 -subswitch 40 /H d -o y
command /S 5 -subswitch 50 /H e -o x
ERROR: Missing variable in run[6]
command /S 7 -subswitch 70 /H g -o x
command /S 8 -subswitch 80 /H h -o y
command /S 9 -subswitch 90 /H i -o x
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • like always the mastermind shows interesting ways. while the array here is not that clearly readable as in unclemeat's example i am thinkin about how to prevent a run with only 3 given vars instaed of 4. A run with vars from different lines of the definition would end in an desaster. – peet Dec 13 '13 at 07:12
  • still wondering about your substituation with the empty lines, what is the trick here? Or better why and how does it work with and not without? – peet Dec 13 '13 at 07:27
  • @peet: See the edit in my answer above. Note that, strictly speaking, you have not including any _array_ in your question; hence Endoro's comment: "please show the `array` in your code"... – Aacini Dec 13 '13 at 11:10
  • Thanks a million for pretty and readable code, i did read about batch and arrays meanwhile and: YES, endoro there is no real array in batching, while at least this is an approximation of an (associative) array - as much as we can achieve in batch. Is it fair for you, sir :), to mark unclemeat's solution anyway for being the first right one? – peet Dec 13 '13 at 17:57
  • I meant that in your code you do not write any Batch _array_ just some _lists_ of comma-separated values, so my first solution use a larger series of comma-separated values that is easier to manage. It is possible to manage arrays in Batch files in an _equivalent_ way of other programming languages; see [this post](http://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script/10167990#10167990). I think that the "Best Answer" should be the one you will use to solve your problem, but you may select whatever you wish; it is OK for me! `;-)` – Aacini Dec 13 '13 at 20:17
  • wow, what a morning reading, impressing code. you got it. most people do not realize that what they use is not that far away from the beginning of it all. and only few know, and "fewer" understand Assembler, so they mostly don't really know what they are doing. i really like your batch database example code, `SIR`. – peet Dec 14 '13 at 05:23
  • Is it possible to get runs ordered natural? See question update please. – peet Dec 14 '13 at 06:59
  • @peet: There are two immediate solutions for the natural order: use a left zero in subscripts less than 10: `set run[01]=1,10,a,x` OR define the number of runs in a variable: `set N=20` and slightly modify the program to use a `for /L %%i in (1,1,%N%)...` instead of the current `for /F ... in ('set run[') ...`. However, I suggest you to modify the program in order to get runs data _from a .txt file_ instead of Batch code! This way, you (and your colleages) may write run data in any way you wish, so I think this method would solve _all_ your problems... – Aacini Dec 14 '13 at 16:58
0
@echo off

for %%i in (
    "1,10,a,x"
    "2,20,b,y"
    "3,30,c,x"
    "4,40,d,y" 
    "5,50,e,x" 
    "6,60,f,y" 
    "7,70,g,x" 
    "8,80,h,y" 
    "9,90,i,x"
) do for /f "delims=, tokens=1-4" %%A in ("%%~i") do (
    echo %%A %%B %%C %%D
)

%%A through %%D can correspond to your %var1% through %var4%.

Let me know if you need anything explained.

unclemeat
  • 5,029
  • 5
  • 28
  • 52
  • `command /S %%A -subswitch %%B /H %%C -o %%D` would this work in your loop too? – peet Dec 13 '13 at 00:57
  • Should definitely work. Try it out and let me know. Add it after the `echo` - or replace the echo with your command. – unclemeat Dec 13 '13 at 01:12
  • although the `'echo %%~i'` could usefully be replaced by `"%%~i"` – Magoo Dec 13 '13 at 01:17
  • Right you are - that bit cleaner. Cheers. – unclemeat Dec 13 '13 at 02:06
  • @peet, if this has worked for you, please mark it as the correct answer. If not, let me know. – unclemeat Dec 13 '13 at 03:14
  • I will try later today, just stood up right now :) One point i did not get till now. What happens if one would modify my script and maybe would only set 3 vars in one line accidently? – peet Dec 13 '13 at 07:06
  • i am thinkin about how to prevent a run with only 3 anewed given vars instead of 4. A run with vars from different lines of the definition would end in an desaster, and if one only would define a line with 3 vars the 4th would stay the old right? Can we set them empty before each Loop easiely? I'd like to stay that easy with the code, small and simple, so everybody can read and understand. – peet Dec 13 '13 at 07:24
  • If four variables weren't defined in an iteration of the loop then, no, the variables wouldn't retain their previous values. For example, if an iteration of this loop only had three values to work with, it would expand %%D to "%%D" and not, say, "x". – unclemeat Dec 13 '13 at 08:57
  • If you are setting these values manually why would you add error handling for incorrect values? – unclemeat Dec 13 '13 at 09:09
  • because one day a collegue will use the script and life teached me that if there is a possibility to do it false, they will find and do so :) a second nice option in aacini's code is to use remarks and strucure the lines, but thanks a million though for your efforts and input - i really apprecciate. – peet Dec 14 '13 at 09:24
0
@ECHO OFF &SETLOCAL
setlocal EnableDelayedExpansion

set $VAR=RUN1,RUN2,RUN3,RUN4,RUN5,RUN6,RUN7,RUN8,RUN9
set var1=1,2,3,4,5,6,7,8,9
set var2=10,20,30,40,50,60,70,80,90
set var3=a,b,c,d,e,f,g,h,i
set var4=x,y,x,y,x,y,x,y,x

call:Send 4
exit /b

:send
set $c=1
for %%a in (%$var:,= %) do (echo %%a
                            set $run=
                            call:final %1
                            set /a $c+=1)                                
exit /b

:final    
for /l %%b in (1,1,%1) do (set $liste=!var%%b!
                           for /f "tokens=%$c% delims=," %%x in ('echo !$liste!') do set $run=!$run! %%x)

set $c1=1
set $comm=
for %%a in (!$run!) do (if !$c1! equ 1 set $Comm=Command /s %%a
                        if !$c1! equ 2 set $comm=!$comm! -subswitch %%a /H
                        if !$c1! equ 3 set $comm=!$comm! %%a -O
                        if !$c1! equ 4 set $comm=!$comm! %%a
                        set /a $c1+=1)

echo !$comm!
SachaDee
  • 9,245
  • 3
  • 23
  • 33
  • Looks very impressing, while i would prefer to go 9 times 4 vars, while your example would make it possible to make shure that 4 vars are given i guess, while i do not see how :) – peet Dec 13 '13 at 07:08
  • Do you want to include a test, who check if you really have 4 vars ? – SachaDee Dec 13 '13 at 10:05
  • nice and structured code, while no one of my collegues could follow it, lol. too the top level for structure is the other way round 9 times 4 vars. thank you anyway, maybe you could help me [here](http://stackoverflow.com/questions/20299266/ip-verification-in-batch-script-first-match-by-findstr-secondly-verify-by-for)? – peet Dec 14 '13 at 09:34