Как перебрать массив в пакетном режиме?
Я создал такой массив:
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 не входит в цикл. Почему это? Как я могу продолжить?
Ответы
Ответ 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"