Массивы в bat / cmd файлах.
В командных файлах не предусмотрено создание агрегатных переменных. Однако в какой-то степени можно имитировать массивы в командных файлах.
Мы уже рассматривали в разделе Примеры работы с датой, временем пример определения дня недели по номеру. Приведу его еще раз.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Day2Name %d% day
:: By: Ritchie Lawrence, 2002-10-04. Version 1.0
:: Func: Returns the day of week from the day number, 1=Monday, 7=Sunday.
:: For NT4/2000/XP/2003.
:: Args: %1 day number to convert to name of day of week, 1 to 7 (by val)
:: %2 var to receive name of day of week (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /f "tokens=%1" %%a ^
in ('echo Понедельник Вторник Среда Четверг Пятница Суббота Воскресение') ^
do set %2=%%a
exit /b 0
Фактически здесь предлжен вариант работы с массивом констант. Данные собираются в переменную с разделителями и, используя номер токена, по запросу извлекается требуемая часть.
Там же приведен еще один вариант решения этой задачи. На мой взляд, менее наглядный.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Day2Name %d% day
set map=1-Понедельник;2-Вторник;3-Среда;4-Четверг;^
5-Пятница;6-Суббота;7-Воскресение;
CALL SET v=%%map:*%1-=%%
SET v=%v:;=&rem.%
set %2=%v%
exit /b 0
Здесь из переменной сначала удаляются данные, предшествующие требуем, а затем комментируются данные, следующие за требуемыми.
Выше были рассмотрены варианты имитации работы с массивом констант. Теперь перейдем к примерам, более похожим на массивы.
Напомним, что нет жестких ограничений на использование символов [ и ] в имени переменной. Так же можно в имени использовать символ точка. Вот этим мы и воспользуемся. Сначала рассмотрим вариант отделения индекса от имени через точку.
for /l %%i in ( 0, 1, 9 ) do (
set /a arr.%%i=%%i
)
Вероятно, несколько непривычно использование переменной в части имени другой переменной. Но именно это помогло создать 10 переменных от arr.0 до arr.9 и присвоить им значения. Теперь рассмотрим обращение к элементам такого псевдомассива.
Если номер элемента не переменная, а известен, то здесь вcе просто:
set /a mmin=arr.0
set /a mmax=arr.0
Если номер элемента вычисляется, то приемы обращение к нему несколько похожи на примеры извлечения подстроки, когда начальная позиция и/или длина подстроки - переменные. ( пример извлечения подстроки приведен в разделе Примеры. Работа со строковыми данными )
Рассмотрим различные варианты.
setlocal ENABLEEXTENSIONS
SetLocal EnableDelayedExpansion
::::::::::
set /a n=4
::::::::::
set rr=!arr.%n%!
::::::::::
call set dd=%%arr.%n%%%
::::::::::
call :izvl 3 ff
echo %ff%
::::::::::
:izvl
set %2=!arr.%1!
exit /b 0
Ну и более полный пример работы с псевдомассивами - получение минимального и максимального значений элементов массива:
@echo off
setlocal ENABLEEXTENSIONS
SetLocal EnableDelayedExpansion
for /l %%i in ( 0, 1, 9 ) do (
set /a arr.%%i=%%i
)
set /a mmin=arr.0
set /a mmax=arr.0
for /l %%i in ( 9, -1, 0 ) do (
if !mmax! LSS !arr.%%i! ( set mmax=!arr.%%i! )
if !mmin! GTR !arr.%%i! ( set mmin=!arr.%%i! )
)
echo min=!mmin! max=!mmax!
Заметим, что элементы такого псевдомассива могут содержать как строковые, так и числовые значения. Кроме того, подобная техника позволяет моделировать многомерные массивы.
Если вы сторонник более привычной нотации -
с квадратными скобками - arr[%n%], то можно просто переписать предложенный пример
@echo off
setlocal ENABLEEXTENSIONS
SetLocal EnableDelayedExpansion
for /l %%i in ( 0, 1, 9 ) do (
set /a arr[%%i]=%%i
)
set /a mmin=arr[0]
set /a mmax=arr[0]
for /l %%i in ( 9, -1, 0 ) do (
if !mmax! LSS !arr[%%i]! ( set mmax=!arr[%%i]! )
if !mmin! GTR !arr[%%i]! ( set mmin=!arr[%%i]! )
)
echo mmin=%mmin% mmax=!mmax!
::::::::::
set /a n=4
echo %arr[8]%
echo !arr[%n%]!
::::::::::
call set dd=%%arr[%n%]%%
echo dd=%dd%
::::::::::
call :izvl1 3 ff
echo ff=%ff%
::::::::::
goto :eof
:izvl1
set %2=!arr[%1]!
exit /b 0
В завершение приведу ссылку на более серьезную работу. Работа с массивами в bat.
-------------------------------------------------------------------------------------------------------
Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).
Новый раздел о средствах командной строки в рамках этого же проекта расположен здесь