Wow, tienes muchos problemas con ese pequeño fragmento de código :-)
A su código publicado le falta la opción SET / A. Supongo que su código real lo tiene.
La razón por la que su código falla con un error de sintaxis es porque el comando dentro de la cláusula FOR IN () se ejecuta a través de un cmd /C yourCommandHere
comando. Cuando cmd /C
se analiza el comando implícito , se trata =
como un delimitador de token a menos que se escape o se cite. Cualquier cadena consecutiva de delimitadores de token se convierte en una sola <space>
antes de que su comando se ejecute realmente en un nuevo hilo CMD utilizando la semántica de línea de comando. La lista de delimitadores de tokens es ,
;
=
<space>
<non-breaking space>
y <tab>
.
Citar el comando eliminará el error de sintaxis:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A "RND=%%RANDOM%%*5/32768+1"') DO ECHO SOME[%%i] %%j
Como se escapará el =
:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A RND^=%%RANDOM%%*5/32768+1') DO ECHO SOME[%%i] %%j
Pero realmente no necesita asignar el número aleatorio a una variable. El comando FOR IN () se ejecuta dentro de un contexto de línea de comando, y SET / A imprimirá el valor calculado en stdout cuando se ejecute dentro de un contexto de línea de comando. Entonces, lo siguiente también elimina cualquier error de sintaxis con efectivamente los mismos resultados:
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A %%RANDOM%%*5/32768+1') DO ECHO SOME[%%i] %%j
Aquí hay un método más simple para dar un resultado del 1 al 5 (mod aleatorio 5 + 1):
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET /A %%RANDOM%% %% 5 + 1') DO ECHO SOME[%%i] %%j
Pero dudo seriamente que cualquiera de las soluciones anteriores dé el resultado deseado.
Algo muy peculiar sucede con el valor de %RANDOM%
. Su uso de %%RANDOM%%
correctamente hace que la expresión se evalúe en cada iteración. Pero por alguna razón, el número aleatorio es casi constante para cualquier ejecución dada. De vez en cuando, una de las iteraciones variará, pero para la mayoría de las ejecuciones, cada iteración obtiene un valor constante. Creo que debe tener algo que ver con el valor inicial del generador de números aleatorios. Quizás el generador de números aleatorios se inicia con un valor inicial cada vez que se inicia una sesión CMD, y el valor inicial solo cambia muy lentamente. Recuerde que la cláusula FOR IN () se ejecuta en una nueva sesión CMD.
Aquí hay un programa de prueba que demuestra que %%test%%
se está reevaluando adecuadamente cada iteración. También muestra cómo %%random%%
se mantiene casi constante dentro de una carrera.
@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
)
Aquí está la salida de 2 ejecuciones del código anterior. Observe cómo la primera ejecución tiene una variación en el número aleatorio. La segunda carrera tiene un valor aleatorio constante.
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
Realmente no hay razón para poner el cálculo de números aleatorios dentro de una cláusula FOR / F IN ('comando'). Todo es mucho más simple si usa SET / A con expansión retrasada directamente dentro de su bucle externo.
Creo que lo siguiente puede ser lo que estás buscando:
@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]!
)
Aquí hay algunos resultados de muestra:
C:\test>test
1: SOME[3]="CC"
2: SOME[5]="EE"
3: SOME[2]="BB"
4: SOME[2]="BB"
5: SOME[5]="EE"
EDITAR
Aquí hay una mejor evidencia de que el aleatorizador para la sesión CMD se reinicia y la semilla cambia lentamente.
@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"
--SALIDA--
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