From Batch script below:
@echo off
setlocal enableDelayedExpansion
set menu=One Two Three
SET order=0
for %%A in (%menu%) do (
set /a order+=1
echo [!order!] %%A
)
pause
The output:
[1] One
[2] Two
[3] Three
How to make the output like this?
[A] One
[B] Two
[C] Three
Replacing Number sequence
with Alphabet sequence
I created this macro for easy to reuse menu's. simply expand the Menu variable with a list of the options to be selected from as per the example included.
@Echo off
REM Setlocal EnableDelayedExpansion
======================================================================================
REM Modular menu macro by T3RRY T3RR0R
REM https://pastebin.com/K3LpJXh5
REM to discuss batch macro techniques Join https://discord.gg/HCSEC829F9
================================================ REM = Menu macro Definition BEGIN
REM IMPORTANT - Defines the following Variables: \n Console_Width Menu*
REM Reserved Variable Prefix: Menu
REM - Do not define other variables with the leading name 'Menu' in your
REM script to prevent any possibility of variable contamination.
REM Version Update 24/01/2024
REM Incorporate ADS redirection + More command to handle cases where
REM Menu output exceeds the consoles height and scrolling is disabled.
REM Version Update 21/01/2024
REM Variable Structure reworked to minimize variable reservations required by
REM constraining all internal variables to a single prefix: menu*
REM Macro help and usage now embeded in the Macro.
REM Expanding the macro without arguments will now display the help output.
REM return variables are now named:
REM Menu{String}
REM Menu{Key}
REM Menu{Number}
REM Macro definition and expansion environment trickery pioneered by Jeb
REM Recommended Learning resources:
REM https://www.dostips.com/forum/viewtopic.php?t=9265#p60294
REM https://www.dostips.com/forum/viewtopic.php?f=3&t=10983&sid=f6937e02068d93bc5a97ef63d4e5319e
REM Macros with arguments learning resource:
REM https://www.dostips.com/forum/viewtopic.php?f=3&t=1827
(Set \n=^^^
%= Newline var \n for multi-line macro definition - Do not modify This codeblock. =%)
REM - use REM / remove REM on the below line to enable / disable menu dividing line
REM Goto :NoDividingLine
REM Enable DE environment to perform variable concatenation within a for loop
Setlocal EnableDelayedExpansion
REM Get console width for dividing line
For /f "usebackq tokens=2* delims=: " %%W in (`mode con ^| %__APPDIR__%findstr.exe /LIC:"Columns"`) do Set /A Console_Width=%%W
Set "Menu_Div=" & For /L %%i in (1 1 %Console_Width%)Do Set "Menu_Div=!Menu_Div!-"
Endlocal & Set "Menu_Div=%Menu_Div%"
:NoDividingLine
REM Menu internal variables
REM keymap. translates literal keypress to the numeric position of the item in the menu list
Set /a Menu@0=36,Menu@1=1,Menu@2=2,Menu@3=3,Menu@4=4,Menu@5=5,Menu@6=6,Menu@7=7,Menu@8=8,Menu@9=9,Menu@a=10,Menu@b=11,Menu@c=12,Menu@d=13,Menu@e=14,Menu@f=15,Menu@g=16,Menu@h=17,Menu@i=18,Menu@j=19,Menu@k=20,Menu@l=21,Menu@m=22,Menu@n=23,Menu@o=24,Menu@p=25,Menu@q=26,Menu@r=27,Menu@s=28,Menu@t=29,Menu@u=30,Menu@v=31,Menu@w=32,Menu@x=33,Menu@y=34,Menu@z=35
REM Valid choice characters
Set "Menu.Keys=123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
Set "Menu.Hash=Header"
REM Menu macro Usage: %Menu% "quoted" "list of" "options"
%= Outer for loop allows environment independant definition =% For /f %%! in ("! ^! ^^^!") Do ^
%= IMPORTANT - No whitespace permitted here =%Set ^"Menu=For %%n in (1 2)Do if %%n==2 (%\n%
If defined Menu{Args} (%\n%
%= Switch control via !! Expansion outcome =% for /f "tokens=2" %%? in ("%%!%%! 1 0") do (%\n%
%= Switch - Setlocal / NOP =% If %%~? EQU 1 SetLocal EnableDelayedExpansion%\n%
%= Output Dividing Line =% ^>"%~f0:MenuMacro:$Data" (%\n%
%= If Header Substitute Output substitution =% If not "Header" == "%%!Menu.Hash%%!" (%\n%
If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
Echo(Header%\n%
)%\n%
If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
%= Reset Menu.# index for Menu.Item[#] =% Set "Menu.#=0"%\n%
%= Undefine choice command key list =% Set "Menu.Chars="%\n%
%= Redirect output to ADS; For Each in List =% For %%G in (%%!Menu{Args}%%!)Do (%\n%
%= For Menu.Item Index value =% For %%i in (%%!Menu.#%%!)Do If not %%i GTR 35 (%\n%
%= Build the Choice key list =% Set "Menu.Chars=%%!Menu.Chars%%!%%!Menu.Keys:~%%i,1%%!"%\n%
%= Define Menu.Item array =% Set "Menu.Item[%%!Menu.Keys:~%%i,1%%!]=%%~G"%\n%
%= Assign String for safe output =% Set "Menu.Output=%%~G"%\n%
%= Display as [key] Option String =% Echo([%%!Menu.Keys:~%%i,1%%!] %%!Menu.Output%%!%\n%
%= Increment Menu.# Index var =% Set /A "Menu.#+=1"%\n%
%= Close Menu.# expansion loop =% )%\n%
%= Close Menu{Args} String loop =% )) %\n%
%= Read output in from ADS to permit More =% More ^< "%~f0:MenuMacro:$Data"%\n%
%= Output Dividing Line =% If Defined Menu_Div Echo(%%!Menu_Div%%!%\n%
%= Select option by character index =% For /f "delims=" %%o in ('%__APPDIR__%Choice.exe /N /C:%%!Menu.Chars%%!')Do For /f "tokens=1,2 delims=;" %%V in ("%%!Menu.Item[%%o]%%!;%%!Menu@%%o%%!")Do (%\n%
%= Switch - Endlocal / NOP ; returnVars =% ( If %%~? EQU 1 EndLocal ) ^& (%\n%
%= exit [sub]script w/out modifying option =% If /I "%%V" == "Exit" Exit /B 2%\n%
%= Assign 'Menu{String}' w/literal string =% Set "Menu{String}=%%V"%\n%
%= Assign 'Menu{key}' with key pressed =% Set "Menu{Key}=%%o"%\n%
%= Assign 'Menu{Number} with list position =% Set "Menu{Number}=%%~W"%\n%
%= Reset Menu Argument variable =% Set "Menu{Args}="%\n%
%= Set errorlevel to match Menu{Number} =% CMD /C Exit %%~W%\n%
%= Close Menu macro processing loops =% ) ) )%\n%
)Else (%\n: Show Macro Help if no arguments supplied - will not display if expanded menu variable has trailing whitespace =%
CLS%\n%
Echo(Usage:%\n%
Echo(%\n%
Echo(%%Menu%%%\n%
Echo( Output this help info, Set Errorlevel 0%\n%
Echo(%\n%
Echo(%%Menu%% "DoubleQuoted List" "Of Options"%\n%
Echo( Output the Menu list, Take input%\n%
Echo(%\n%
Echo(%%Menu:Header=Your Custom Header%% "DoubleQuoted List" "Of Options"%\n%
Echo( Outputs substituted Header, Output Menu list; Take input%\n%
Echo(%\n%
Echo(Return Variables:%\n%
Echo( Menu{String} : The literal String%\n%
Echo( Menu{Key} : The Key Pressed%\n%
Echo( Menu{Number} : The list position of the option as an Integer%\n%
Echo( IE: Option 1 = 1, Option A = 10%\n%
Echo( Note: The Errorlevel is also set to this value%\n%
Echo(%\n%
Echo( Note: The number of options available is limited to 36.%\n%
Echo(%\n%
Echo( Important: The following variable prefix is reserved: Menu%\n%
Echo(%\n%
Pause%\n%
CLS%\n%
%= If Menu expanded without Args Set Errorlevel 0 =%(Call )%\n%
)%\n%
%= Capture Macro input - Options List =%)Else Set Menu{Args}=^"
========================================== REM = Menu Macro Definition END
REM Below lines Not required if macro definition is pasted within another script
REM Load macro from a calling script using any arg within the Findstr Search strings below; Return to caller
If Not "%~1" == "" Echo(%*|%SystemRoot%\System32\findstr.exe /LI "/D Def Menu Load Menu Get" 2>&1 > nul && Exit /b 0
REM Below lines Are Demo Only.
REM Everything from this line and below is example usage only.
REM demonstrates retention of last option variables upon selection of exit
REM Call:DemoMenu
REM Echo(You last chose %Menu{String}% by pressing %Menu{Key}% at index %Menu{Number}%
REM Exit /b 0
REM view macro usage by expanding without arguments
%Menu%
REM Apply Header using substring when expanding macro
%Menu:Header=This is a demo Header% "See next demo" "Close after seeing this demo's output"
Echo(You Pressed %Menu{key}% to Choose '%Menu{String}%'; option number = %Menu{Number}%
If %Menu{Number}% EQU 2 Exit /b 0
Pause
:DemoMenu
CLS
%Menu% List of your Options here. "Double qoute" "Delimited Strings" filler to extend option count. caps at 36 \ / \ / \ / \ / \ / \ / \ / \ / \ / \ . Exit \ .
Echo(You Pressed %Menu{key}% to Choose '%Menu{String}%'; option number = %Errorlevel%
Pause
Goto:DemoMenu