werejago wrote: ↑09 Oct 2020 06:26
For example could you break down the script?
Code: Select all
@echo off & Goto :Main
rem /*_________________________________________Functions */
:GetIN
Setlocal EnableDelayedExpansion
Set "Input=(Set "nVar="&Echo/Enter # Digit Integer:&(For /L %%. in (1 1 #)Do For /F "Delims=" %%G in ('Choice /N /C 0123456789')Do (<Nul Set /P"=%%G"&Set "nvar=^^!nVar^^!%%G"))&Echo/&Echo/Confirm: ^^!nVar^^! Y/N & For /F "Delims=" %%v in ('Choice /N')Do (If /I "%%~v"=="n" (Goto :retry)))"
:retry
%Input:#=8% & Echo/Var [!nVar!] Confirmed
Endlocal & Set "%1=%nVar%" 2> Nul
Exit /B 0
rem /*_________________________________________Script Body */
:Main
set "file=Sensor Serialization.txt"
<"%file%" set /p "line1="
Call :GetIn Num
setlocal EnableDelayedExpansion
>"!file!.~tmp" echo(!line1!
>>"!file!.~tmp" echo(!num!
<"!file!" >>"!file!.~tmp" more +2
move /y "!file!.~tmp" "!file!"
Endlocal
First up:
- Control script flow - prevent unwanted execution of function labels by using Goto :main label
Code: Select all
:GetIN
Setlocal EnableDelayedExpansion
Set "Input=(Set "nVar="&Echo/Enter # Digit Integer:&(For /L %%. in (1 1 #)Do For /F "Delims=" %%G in ('Choice /N /C 0123456789')Do (<Nul Set /P"=%%G"&Set "nvar=^^!nVar^^!%%G"))&Echo/&Echo/Confirm: ^^!nVar^^! Y/N & For /F "Delims=" %%v in ('Choice /N')Do (If /I "%%~v"=="n" (Goto :retry)))"
- Called label :GetIn uses %1 as a return var to return the accepted input value
- Input Macro: Uses For /F loops to iterate over the choice command a number of times equal to the value substituted for # when the macro is expanded. Parenthesis within the macro's definition is used to seperate the for loop that is used to select and concatenate input values from the For /F loop over choice that is used to accept or reject the value, with the script looping to the retry label if the concatenated value is rejected.
- because the macro is defined in a delayed expansion environment, escaping of the ! character with ^^ is required to prevent the parser expanding the string as a variable during the macro's definition. Once defined in this manner, a macro contains the literal value of "!string!" as opposed to "variables value".
Code: Select all
:retry
%Input:#=8% & Echo/Var [!nVar!] Confirmed
- "%Input:#=8%" is the expansion of the input macro, using substring modification syntax to supply the input length
- "& Echo/Var [!nVar!] Confirmed" executes after the input macro finishes executing, once a value has been accepted.
Code: Select all
Endlocal & Set "%1=%nVar%" 2> Nul
Exit /B 0
- using concatenation of the Endlocal & Set command on the same line (or within code block) allows a variable value to be returned across the endlocal barrier.
- "2> Nul" redirects a syntax error for some reason the function is called without a parameter for a return var
- "Exit /B 0" ends the command process created with the Call command and returns to the parent script from the point immediately after the call
A clearer, remarked expression of the above input macro used in the :GetIn function,as it would be scripted if it was used whole as a function as opposed to a macro:
Code: Select all
:GetIN <ReturnVar> <Required String Length as Integer>
rem /* Ensure environment that allows for concatenation of variables with values with correct values during code blocks */
Setlocal EnableDelayedExpansion
rem /* ensure no conflict with any potential pre-existing nVar variable used to build input string */
Set "nVar="
Echo/Enter a %2 Digit Integer [0-9]:
rem /* use a For /L loop n times to enact a for /F loop on the Choice command, with n being the value passed as Arg 2. [Substring modification replacing # in macro] */
rem /* the for /F loop catches the literal character entered as the choice instead of the errorlevel, each input is displayed on same line using Set /P */
rem /* Note: /N switch MUST be used and /M switch CANNOT be used to correctly catch input from choice using the For /F loop */
For /L %%. in (1 1 %2)Do For /F "Delims=" %%G in ('Choice /N /C 0123456789')Do (
<Nul Set /P"=%%G"
rem /* Build the string using delayed expansion to update it with each new input */
Set "nvar=!nVar!%%G"
)
Echo/
Echo/Confirm: !nVar! Y/N
rem /* Use default choice to confirm entered string is acceptable, send to retry label if rejected */
For /F "Delims=" %%v in ('Choice /N')Do If /I "%%~v"=="n" (Goto :retry)
Echo/%1 [!nVar!] Confirmed
rem /* end the Setlocal used in the function and tunnel the return value to Arg 1 return variable by concatenating the commands on the same line */
Endlocal & Set "%1=%nVar%" 2> Nul
rem /* Exit the command process initiated by Call :GetIn and return to the script immedatialy after the point the call was initiated */
Exit /B 0
"<" , ">" and ">>" are redirection operators that instruct cmd.exe what source to read or write input from, with:
- "<" being read
- ">" being overwrite
- ">>" being Append
- "Set /P" can only ever read the first line of input from a file as a single command.
Not used in this script, however: A code block can be used to read multiple lines from a file with multiple Set /P commands Eg:
Code: Select all
<"file.ext" (
Set /P "line1="
Set /P "line2="
)
- Overwite / Write new "!file!.~tmp" with output line value of !line1!
- Append value entered for num via :GetIn function and input macro to "!file!.~tmp"
Code: Select all
<"!file!" >>"!file!.~tmp" more +2
- read file "!file!" and append lines 3 and onwards to "!file!.~tmp", using the +n syntax of the more command to 'skip' the first two lines.
- in the context of macro definition and expansions, allows control of how strings are parsed at the time of expansion by inhibiting the expansion of yet to be defined variables during the macro's definiton.
- In the context of expanding file names from variables or contents of lines from files that have been assigned to variables, allows parsing of content containing poison characters that would otherwise cause the command interpreter to fail. Can present a problem if filenames or contents contain ! characters, as they will attempt to expand during parsing when they are defined. If this is likely to present a problem, This can be avoided by defining such variables in an Environment where delayed expansion is disabled, and enabling delayed expansion only when the values of such variables need to be assessed or output.
Apologies if I've broken it down too far, I've made no assumptions regarding your current knowledge base.