Подтвердить что ты не робот

Как перебрать массив в пакетном режиме?

Я создал такой массив:

set sources[0]="\\sources\folder1\"
set sources[1]="\\sources\folder2\"
set sources[2]="\\sources\folder3\"
set sources[3]="\\sources\folder4\"

Теперь я хочу выполнить итерацию по этому массиву:

for %%s in (%sources%) do echo %%s

Это не работает! Кажется, что script не входит в цикл. Почему это? Как я могу продолжить?

4b9b3361

Ответ 1

Если вы не знаете, сколько элементов имеет массив (похоже, это так), вы можете использовать этот метод:

for /F "tokens=2 delims==" %%s in ('set sources[') do echo %%s

Обратите внимание, что элементы будут обрабатываться в алфавитном порядке, то есть, если у вас есть более 9 (или 99 и т.д.) элементов, индекс должен иметь ноль в элементах 1..9 (или 1..99 и т.д.)

Ответ 2

Другая альтернатива, использующая определенные и цикл, который не требует отсроченного расширения:

set Arr[0]=apple
set Arr[1]=banana
set Arr[2]=cherry
set Arr[3]=donut

set "x=0"

:SymLoop
if defined Arr[%x%] (
    call echo %%Arr[%x%]%%
    set /a "x+=1"
    GOTO :SymLoop
)

Убедитесь, что вы используете "call echo", поскольку эхо не будет работать, если у вас нет задержки с расширением и использованием! вместо %%

Ответ 3

Если вам не нужны переменные среды, выполните следующие действия:

for %%s in ("\\sources\folder1\" "\\sources\folder2\" "\\sources\folder3\" "\\sources\folder4\") do echo %%s

Ответ 4

Это один из способов:

@echo off
set sources[0]="\\sources\folder1\"
set sources[1]="\\sources\folder2\"
set sources[2]="\\sources\folder3\"
set sources[3]="\\sources\folder4\"

for /L %%a in (0,1,3) do call echo %%sources[%%a]%%

Ответ 5

Я так использую, важно то, что переменная имеет длину всего 1, например %% a, а не как %% repo:

for %%r in ("https://github.com/patrikx3/gitlist" "https://github.com/patrikx3/gitter" "https://github.com/patrikx3/corifeus" "https://github.com/patrikx3/corifeus-builder" "https://github.com/patrikx3/gitlist-workspace" "https://github.com/patrikx3/onenote" "https://github.com/patrikx3/resume-web") do (
   echo %%r
   git clone --bare %%r
)

Ответ 6

Для потомков: я просто хотел предложить небольшую модификацию на @dss, иначе отличный ответ.

В текущей структуре способ проверки DEFINED вызывает неожиданный вывод, когда вы назначаете значение от Arr во временную переменную внутри цикла:

Пример:

@echo off
set Arr[0]=apple
set Arr[1]=banana
set Arr[2]=cherry
set Arr[3]=donut

set "x=0"

:SymLoop
if defined Arr[%x%] (
    call set VAL=%%Arr[%x%]%%
    echo %VAL%
    REM do stuff with VAL
    set /a "x+=1"
    GOTO :SymLoop
)

Это фактически приводит к следующему неправильному выводу

donut
apple
banana
cherry

Последний элемент печатается первым. Чтобы исправить это, проще инвертировать проверку DEFINED, чтобы она перепрыгивала через цикл, когда мы закончили с массивом, а не выполняем его. Вот так:

@echo off
set Arr[0]=apple
set Arr[1]=banana
set Arr[2]=cherry
set Arr[3]=donut

set "x=0"

:SymLoop
if not defined Arr[%x%] goto :endLoop
call set VAL=echo %%Arr[%x%]%%
echo %VAL%
REM do your stuff VAL
SET /a "x+=1"
GOTO :SymLoop

:endLoop
echo "Done"

Это независимо от того, что вы делаете внутри SymLoop, всегда производит желаемый правильный вывод

apple
banana
cherry
donut
"Done"