yakoffka.ru
грабли, костыли и велосипеды php, css, html, js и прочего

костыли cmd

Костыли«Обходной приём, workaround, паллиатив, на техническом жаргоне — «костыль» — относительно быстрое и простое решение проблемы, применяемое для срочного устранения её последствий, но не влияющее на причины её возникновения... Основной проблемой обходных приёмов является то, что их применение снижает мотивацию к радикальному решению проблемы и временный по своей сути «костыль» остаётся в качестве постоянного решения, сам по себе становясь источником дополнительных проблем»

wikipedia.org

Использование составных переменных

В случае, когда мы заранее не знаем имя переменной, к которой нам необходимо обратиться, стоит использовать 'составную переменную'. Например, мы имеем следующий код, в котором объявляются некие переменные:
Code:
rem ввод исходных данных: set /a "num_fruit=5" set /a fruit_param_1_1=2 && set "fruit_param_2_1=red" && set "fruit_param_3_1=apple" set /a fruit_param_1_2=5 && set "fruit_param_2_2=orange" && set "fruit_param_3_2=orange" set /a fruit_param_1_3=1 && set "fruit_param_2_3=green" && set "fruit_param_3_3=pear" set /a fruit_param_1_4=0 && set "fruit_param_2_4=orange" && set "fruit_param_3_4=grapefruit" set /a fruit_param_1_5=6 && set "fruit_param_2_5=yellow" && set "fruit_param_3_5=lemon"
Для обращения к параметрам рандомного фрукта используется составная переменная, имя которой содержит переменную:
Code:
quantity=!fruit_param_1_%rand_fruit%!
Таким образом, используя составную переменную мы без проблем можем обратиться к рандомному фрукту и узнать его параметры:
Code:
rem обращение к рандомному фрукту: call :RND 1 %num_fruit% rand_fruit echo выбираем ссылку в главном меню. выбран фрукт № %rand_fruit%. echo quantity=!fruit_param_1_%rand_fruit%! echo color=!fruit_param_2_%rand_fruit%! echo name=!fruit_param_3_%rand_fruit%! echo.
код функции получения рандомного номера:
Code:
call :RND %min% %max% res ==================================================================================================== :RND set min=%1 set max=%2 set /A res=%min%+(%max%-%min%+1)*%random%/32768 set %3=%res% echo min="%min%"; max="%max%"; res="%res%" exit /b

Использование составных порядковых переменных

Но мы заходим в тупик, если попытаемся вызвать составную переменную в цикле. следующие попытки не сработают:
Code:
for /l %%i in (1, 1, %num_fruit%) do ( set "num=%%i" echo fruit_param_1='!fruit_param_1_!num!!'; echo fruit_param_1='!fruit_param_1_%num%!'; )
В этом случае можно сделать финт ушами:
Code:
for /l %%i in (1, 1, %num_fruit%) do ( echo fruit num='%%i' call :getting_fruit_param_ %%i fruit_param_1 fruit_param_2 fruit_param_3 echo fruit_param_1='!fruit_param_1!'; echo fruit_param_2='!fruit_param_2!'; echo fruit_param_3='!fruit_param_3!'. echo. ) exit :getting_fruit_param_ set i=%1 set %2=!fruit_param_1_%i%! set %3=!fruit_param_2_%i%! set %4=!fruit_param_3_%i%! exit /b
Полный листинг батника:
Code:
@echo off chcp 65001>nul endlocal enabledelayedexpansion setlocal enabledelayedexpansion set "name_script=%~nx0" set "name_scr=%~n0" rem ввод исходных данных: set /a "num_fruit=5" set /a fruit_param_1_1=2 && set "fruit_param_2_1=red" && set "fruit_param_3_1=apple" set /a fruit_param_1_2=5 && set "fruit_param_2_2=orange" && set "fruit_param_3_2=orange" set /a fruit_param_1_3=1 && set "fruit_param_2_3=green" && set "fruit_param_3_3=pear" set /a fruit_param_1_4=0 && set "fruit_param_2_4=orange" && set "fruit_param_3_4=grapefruit" set /a fruit_param_1_5=6 && set "fruit_param_2_5=yellow" && set "fruit_param_3_5=lemon" rem обращение к рандомному фрукту: call :RND 1 %num_fruit% rand_fruit echo выбираем ссылку в главном меню. выбран фрукт № %rand_fruit%. echo quantity=!fruit_param_1_%rand_fruit%! echo color=!fruit_param_2_%rand_fruit%! echo name=!fruit_param_3_%rand_fruit%! echo. rem последовательный вывод в цикле: echo вывод параметров всех фруктов. for /l %%i in (1, 1, %num_fruit%) do ( echo fruit num='%%i' call :getting_fruit_param_ %%i fruit_param_1 fruit_param_2 fruit_param_3 echo fruit_param_1='!fruit_param_1!'; echo fruit_param_2='!fruit_param_2!'; echo fruit_param_3='!fruit_param_3!'. echo. ) pause exit call :RND %min% %max% res ==================================================================================================== :RND set min=%1 set max=%2 set /A res=%min%+(%max%-%min%+1)*%random%/32768 set %3=%res% echo min="%min%"; max="%max%"; res="%res%" exit /b call :getting_fruit_param_ %%i fruit_param_1 fruit_param_2 fruit_param_3 ==================================================================================== :getting_fruit_param_ set i=%1 set %2=!fruit_param_1_%i%! set %3=!fruit_param_2_%i%! set %4=!fruit_param_3_%i%! exit /b