Wow - you have lots of problems with that small snippet of code :-)
Your posted code is missing the SET /A option. I'm assuming your actual code has it.
The reason your code fails with a syntax error is because the command within the FOR IN() clause is executed via a cmd /C yourCommandHere
command. When the implicit cmd /C
command is parsed, it treats =
as a token delimiter unless it is escaped or quoted. Any consecutive string of token delimiters is converted into a single <space>
before your command is actually executed in a new CMD thread using command line semantics. The list of token delimiters is ,
;
=
<space>
<non-breaking space>
and <tab>
.
So quoting the command will eliminate the syntax error:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A "RND=%%RANDOM%%*5/32768+1"') DO ECHO SOME[%%i] %%j
As will escaping the =
:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A RND^=%%RANDOM%%*5/32768+1') DO ECHO SOME[%%i] %%j
But you don't really need to assign the random number to a variable. The FOR IN() command is executed within a command line context, and SET /A will print the computed value to stdout when run within a command line context. So the following also eliminates any syntax error with effectively the same results:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A %%RANDOM%%*5/32768+1') DO ECHO SOME[%%i] %%j
Here is a simpler method to give a result from 1 to 5 (random mod 5 + 1):
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A %%RANDOM%% %% 5 + 1') DO ECHO SOME[%%i] %%j
But I seriously doubt any of the above fixes give your desired result.
There is something very peculiar going on with the value of %RANDOM%
. Your use of %%RANDOM%%
properly causes the expression to be evaluated each iteration. But for some reason, the random number is nearly constant for any given run. Once in a while, one of the iterations will vary, but for most runs, each iteration gets a constant value. I think it must have something to do with the random number generator seed value. Perhaps the random number generator is initiated with a seed value each time a CMD session starts, and the seed value is only changing very slowly. Remember that the FOR IN() clause is executed in a new CMD session.
Here is a test program that demonstrates that the %%test%%
is properly getting re-evaluated each iteration. It also shows how %%random%%
is remaining nearly constant within a run.
@echo off
setlocal
set test=0
for /l %%I in (1 1 5) do for /f "delims=" %%J in ('echo %%test%% %%random%%') do (
echo %%J
set "test=%%I
)
Here is the output from 2 runs of the above code. Note how the 1st run has one variation in the random number. The 2nd run has a constant random value.
C:\test> test
0 20369
1 20373
2 20373
3 20373
4 20373
C:\test> test
0 20379
1 20379
2 20379
3 20379
4 20379
There really is no reason to put the random number computation within a FOR /F IN('command') clause. Everything is much simpler if you use SET /A with delayed expansion directly within your outer loop.
I believe the following may be what you are looking for:
@echo off
setlocal enableDelayedExpansion
SET SOME[1]="AA"
SET SOME[2]="BB"
SET SOME[3]="CC"
SET SOME[4]="DD"
SET SOME[5]="EE"
FOR /L %%i IN (1,1,5) DO (
set /a rand=!random!%%5+1
for %%N in (!rand!) do echo %%i: SOME[%%N]=!SOME[%%N]!
)
Here is some sample output:
C:\test>test
1: SOME[3]="CC"
2: SOME[5]="EE"
3: SOME[2]="BB"
4: SOME[2]="BB"
5: SOME[5]="EE"
EDIT
Here is better evidence that the randomizer for CMD session is reseeded, and the seed changes only slowly.
@echo off
setlocal enableDelayedExpansion
echo Within a single CMD session, every ^^!random^^! gets a new value.
for /l %%N in (1 1 10) do call echo !time! !random! !random!
echo(
setlocal disableDelayedExpansion
echo But each CMD session !random! is reseeded,
echo and the seed only changes once per second,
echo and the inital value changes slowly:
for /l %%N in (1 1 30) do cmd /v:on /c "echo !time! !random! !random!&for /l %%A in (1 1 50000) do @rem"
--OUTPUT--
Within a single CMD session, every !random! gets a new value.
11:12:10.37 17810 1733
11:12:10.37 8919 24464
11:12:10.37 9931 2137
11:12:10.37 28574 16630
11:12:10.37 30379 23234
11:12:10.37 22410 31740
11:12:10.38 15479 14080
11:12:10.38 812 23616
11:12:10.38 1384 25909
11:12:10.38 2733 1947
But each CMD session !random! is reseeded,
and the seed only changes once per second,
and the inital value changes slowly:
11:12:10.39 4552 6316
11:12:10.50 4552 6316
11:12:10.61 4552 6316
11:12:10.71 4552 6316
11:12:10.82 4552 6316
11:12:10.92 4552 6316
11:12:11.03 4555 17064
11:12:11.14 4555 17064
11:12:11.24 4555 17064
11:12:11.35 4555 17064
11:12:11.45 4555 17064
11:12:11.56 4555 17064
11:12:11.67 4555 17064
11:12:11.77 4555 17064
11:12:11.88 4555 17064
11:12:11.99 4555 17064
11:12:12.09 4559 27813
11:12:12.20 4559 27813
11:12:12.30 4559 27813
11:12:12.41 4559 27813
11:12:12.51 4559 27813
11:12:12.62 4559 27813
11:12:12.73 4559 27813
11:12:12.83 4559 27813
11:12:12.94 4559 27813
11:12:13.04 4562 5793
11:12:13.15 4562 5793
11:12:13.26 4562 5793
11:12:13.36 4562 5793
11:12:13.47 4562 5793