I suggest using the following code with the second suggestion offered by Aacini used in code and some other improvements:
@echo off
for /F "delims=" %%I in ('npm.bat -v') do set "output=%%I"
move "%NPM_PATH%" "%NPM_PATH%-%output%"
for %%A in (%*) do (
if "%%A" == "--change" (
setlocal EnableDelayedExpansion
cls
set "Count=1"
echo ID : VERSION
echo -------------------------
for /F "tokens=*" %%F in ('dir /A:D /B /ON "%NPM_DIR%"') do (
if !Count! LSS 10 (
echo !Count! : %%F
) else (
echo !Count! : %%F
)
set "dir_!Count!=%%F"
set /A Count+=1
)
echo.
set "id=1"
set /P "id=Enter version ID: (e.g. !dir_1! enter 1): "
for %%I in (!id!) do set "TargetDir=!dir_%%I!"
echo !TargetDir!
endlocal
)
)
Why for %%I in (!id!) do set "TargetDir=!dir_%%I!"
assigns the value of the environment variable with name dir_X
with X
being the entered number stored in environment variable id
is explained in detail in Aacini's answer on Arrays, linked lists and other data structures in cmd.exe (batch) script.
For the applied improvements see:
It is advisable using environment variables with a self-explaining name in CamelCase
notation. This has the advantage of knowing what the variable is for and makes it easier to search for all occurrences of a variable. It is a bit difficult to search for a variable with name c
as a single character often occurs in many strings.
The command set
with option /A
means everything next should be interpreted as arithmetic expression. This means that the string after the equal sign is split up into a list of strings using spaces/tabs as string separators. Each string which could be interpreted as decimal, octal or hexadecimal number is converted to a 32-bit signed integer. All other strings which are not operators are interpreted as name of a variable whose value should be converted to a 32-bit signed integer. If the variable does not exist or has not a number as value, 0
is used for the variable. Then the arithmetic expression is evaluated and the result is converted back from integer to string. Finally the result string is assigned to the environment variable left to the equal sign. So with SET /A c=1
at lot of extra work is done in comparison to SET "c=1"
although the result is the same, a string with value 1
is assigned to variable with name c
. Therefore it is recommended not using /A
on assigning a value to an environment variable except there is a very good reason to do so like a primitive check for string being really a number. Note: An assignment like set /A c=009
results in an error message because of 009
being an invalid octal number and c
is not defined or keeps its current value in case of being already defined while set c=009
works.
When a batch user is prompted for a string, the user has the freedom to just hit RETURN or ENTER without entering anything at all. In this case the environment variable keeps its current value or is still not defined if it was not defined already before prompting the user. This explains why set "id=1"
is present in batch code above before prompting the user. Well, it is not checked if the user has really entered a number and if this number is within 1
... !Count!
, but perhaps this is not really necessary although a typing mistake could always occur.