I need to receive input in a batch file that could potentially contain a numerical hyphen, ie. 1-5 means 1, 2, 3, 4, and 5 as the input from the user.
I know how to take a single character input from the user, but to split the input into 5 (or more) separate entries kind of baffles me.
#echo off
set /P "input=Enter a number or range: "
for /F "tokens=1,2 delims=-" %%a in ("%input%") do (
set lower=%%a
set upper=%%b
)
if not defined upper set upper=%lower%
for /L %%i in (%lower%,1,%upper%) do (
echo Process number %%i
)
You can use for /f with delims to split a string. You can use for /L to loop over a range. Type help for on the command line to read about the type of loops.
#echo off
set /p "input=Enter a number or range: "
REM The user must enter either a plain number or a range. Either way, we split
REM the user input on the minus sign. If there's no minus sign, then only
REM %upper% won't get a value.
for /f "usebackq delims=- tokens=1,2" %%a in ('%input%') do (
set "lower=%%a"
set "upper=%%b"
)
REM If %upper% has a value, then input was a range. Otherwise, input contained
REM a single number.
if not "%upper%"=="" goto :handle_range
echo Single number: %lower%
goto :eof
:handle_range
echo Range %lower% to %upper%
REM We can use the numeric for loop to loop over the full range.
for /l %%i in (%lower%, 1, %upper%) do (
echo %%i
)
goto :eof
Related
I know there are many arithmetic questions on here, but I have not found the specific answer to my question. I have a file with two values in it, the first always higher than the second. Today, the txt file has:
21.04
20.94
What I am trying to do is, via a batch file, subtract the second number from the first, and then insert than on a new line. Any assistance is appreciated.
Just incorporate powershell into the batch file.
to test from cmd:
#for /f %i in ('powershell 21.04 - 20.94') do #echo %i
So you can build a very basic calculator rather easily.
set /p "first=Enter first number: "
set /p "second=Enter Second Number: "
set /p "function=Select Function(+-/): "
powershell %first% %function% %second%
And offcourse you can use a for loop to assign the value to a variable should you want to use it elsewhere in your batch file.
#echo off
set /p "first=Enter first number: "
set /p "second=Enter Second Number: "
set /p "function=Select Function(+-/): "
for /f %%i in ('powershell %first% %function% %second%') do set "result=%%i"
echo %result%
in a batch-file you double the % in meta variables to %%i
Assuming file is called math.txt
#echo off
setlocal enabledelayedexpansion
set cnt=1
for /f "usebackq" %%i in ("d:\math.txt") do (
set var!cnt!=%%i
set /a cnt+=1
)
(powershell %var1% - %var2%)>output.txt
pause
This method works with numbers up to 9 total digits (and any number of decimals) as long as the input numbers have the same number of decimals:
#echo off
setlocal EnableDelayedExpansion
rem Read two numbers
( set /P "num1=" & set /P "num2=" ) < test.txt
rem Adjust *two* numbers for given decimals
set "decimals=2"
for %%i in (1 2) do (
set "num%%i=!num%%i:.=!"
for /L %%d in (1,1,%decimals%) do if "!num%%i:~0,1!" equ "0" set "num%%i=!num%%i:~1!"
)
rem Subtract second number from the first
set /A "result=num1 - num2"
rem Adjust result for given number of decimals
for /L %%d in (1,1,%decimals%) do if "!result:~%decimals%!" equ "" set "result=0!result!"
rem Output result with decimals
echo !result:~0,-%decimals%!.!result:~-%decimals%!
I think this works for reasonably sized numbers:
#echo off
rem read values from file specified as command line parameter
(
set /p value1=
set /p value2=
)<%1
rem split first value into whole and fractional parts
for /f "tokens=1,2 delims=." %%a in ("%value1%") do (
set beforedot1=%%a
set afterdot1=%%b
)
rem reconstruct first value as fixed point number
set afterdot1=%afterdot1%00000
set afterdot1=%afterdot1:~0,6%
set value1=%beforedot1%%afterdot1%
rem split second value into whole and fractional parts
for /f "tokens=1,2 delims=." %%a in ("%value2%") do (
set beforedot2=%%a
set afterdot2=%%b
)
rem reconstruct second value as fixed point number
set afterdot2=%afterdot2%00000
set afterdot2=%afterdot2:~0,6%
set value2=%beforedot2%%afterdot2%
rem subtract values
set /a diff=value1-value2
rem convert fixed point value back
if "%diff:~0,-6%" == "" (
set diff=0.%diff:~-6%
) else (
set diff=%diff:~0,-6%.%diff:~-6%
)
rem remove trailing zeros
:loop
if "%diff:~-1%" == "0" (
set diff=%diff:~0,-1%
goto :loop
)
echo %diff%
I want to create a script that sets specific values, then writes each value into a new line of a text document. After that it should read the document and set new values to a specified line of the text document, then echo those out.
I have tried different values for "skip=#" which didn't change anything. When I tried to not use the "skip=0" option in the first FOR and that makes the batch echo out "Value three" for all values. (Quick edit: I've used this website for information on it so far.)
#ECHO OFF
REM Setting values
SET #valueone=Value one
SET #valuetwo=Value two
SET #valuethree=Value three
REM Saving values
IF EXIST "values.txt" DEL "values.txt"
echo %#valueone% >values.txt
echo %#valuetwo% >>values.txt
echo %#valuethree% >>values.txt
REM Reading values again and echoing them at at the same time.
REM This was separated (first reading then echoing) but it didn't change anything.
FOR /F "skip=0 delims=" %%i IN (values.txt) DO SET #valueonefinal=%%i
echo Value number one:
echo %#valueonefinal%
echo.
FOR /F "skip=1 delims=" %%i IN (values.txt) DO SET #valuetwofinal=%%i
echo Value number two:
echo %#valuetwofinal%
echo.
FOR /F "skip=2 delims=" %%i IN (values.txt) DO SET #valuethreefinal=%%i
echo Value number three:
echo %#valuethreefinal%
pause
Expected output in the console:
Value number one:
Value one
Value number two:
Value two
Value number three:
Value three
Actual output:
delims=" was unexpected at this time.
Value number one:
ECHO is off.
Value number two:
Value three
Value number three:
Value three
I'm not that experienced but I suspect that I may be doing the "skip=#" part wrong. Any help with this is greatly apprechiated!
The option skip=0 is not accepted by the for /F command, the specified number must be in the range from 1 to 231 − 1. To skip no lines just do not provide the skip option at all.
You seem to try to assign the text of a certain line to a variable (for instance, the third one):
FOR /F "skip=2 delims=" %%i IN (values.txt) DO SET #valuethreefinal=%%i
Well, this actually assigns the content of the last line to the variable, because the set command in the body of the loop is executed for all but the skipped lines. More precisely said, the for /F loop iterates over all non-empty lines which do not begin with ; which is the default character of the eol option.
To actually assign the third line to the variable you need to change the code:
rem // Ensure that the variable is initially unset somewhere before:
set "#valuethreefinal="
rem // As soon as the variable is set the `if` condition is no longer going to be fulfilled:
for /F "usebackq skip=2 delims=" %%i in ("values.txt") do if not defined #valuethreefinal set "#valuethreefinal=%%i"
This does not necessarily assign the third line to the variable, it actually assigns the text of the first line after the (two) skipped ones that is not empty and does not begin with ; (remember the eol character).
The usebackq option allows to put quotation marks around the file name. This is not necessary in your situation, but it is when a file name contains SPACEs or other special characters.
I used the undocumented quoted set syntax here because this is safer than the unquoted one, particularly when it comes to special characters and also to avoid unintended trailing white-spaces.
To disable the eol character you could use the undocumented unquoted option string syntax:
for /F usebackq^ skip^=2^ delims^=^ eol^= %%i in ("values.txt") do if not defined #valuethreefinal set "#valuethreefinal=%%i"
As you can see the SPACEs and =-signs are escaped by the caret symbol ^ in order to treat the whole option string as a unit.
This still skips over empty lines though. To prevent this take a loop at this thread: preserve empty lines in a text file while using batch for /f.
Since you want to capture more than a single line you could extend the code to the following:
set "#valueonefinal=" & set "#valuethreefinal=" & set "#valuethreefinal="
for /F usebackq^ delims^=^ eol^= %%i in ("values.txt") do (
if not defined #valueonefinal (
set "#valueonefinal=%%i"
) else (
if not defined #valuetwofinal (
set "#valuetwofinal=%%i"
) else (
if not defined #valuethreefinal (
set "#valuethreefinal=%%i"
)
)
)
)
This can be compressed to:
set "#valueonefinal=" & set "#valuethreefinal=" & set "#valuethreefinal="
for /F usebackq^ delims^=^ eol^= %%i in ("values.txt") do (
if not defined #valueonefinal (
set "#valueonefinal=%%i"
) else if not defined #valuetwofinal (
set "#valuetwofinal=%%i"
) else if not defined #valuethreefinal (
set "#valuethreefinal=%%i"
)
)
A more flexible method is to use pseudo-arrays:
rem // Initialise an index counter:
set /A "INDEX=0"
rem // Assign every line to an element of a pseudo-array:
for /F usebackq^ delims^=^ eol^= %%i in ("values.txt") do (
rem // Increment the index counter:
set /A "INDEX+=1"
rem // Assign the current line to a pseudo-array element:
call set "#valuefinal[%%INDEX%%]=%%i"
)
The (non-empty) lines of the file value.txt are now assigned to variables called #valuefinal[1], #valuefinal[2], #valuefinal[3], etc. (there is no concept of arrays in batch scripting, the variables are exactly the same as yours, #valueonefinal, etc., that is why I use the term "pseudo").
The call command is used here in order to be able to write and read the variable INDEX within the same block of code; just using set "#valuefinal[%INDEX%]=%%i" would result in assigning and therefore overwriting the variable #valuefinal[0] in every loop iteration.
Your problem is that you are parsing the File from Top to bottom, and skipping the First value, what you don't realize is that FOR will set the value to the LAST item it found. This means that the script as written can only ever return the last item in the values file.
To deal with this you could:
Break the loop on the first match and return that result.
Remove values as they are matched
I like to Break the loop.
First let me make you code a little more streamlined so we can re-write it multiple times to show each
This is going to work exactly as your existing code but now we can easily add more values and loop them in a quick go.
Your Original Code Refactored:
#( SETLOCAL EnableDelayedExpansion
ECHO OFF
SET "_ValuesFile=%~dp0values.txt"
REM Remove Old Values File
DEL /F /Q "!_ValuesFile!" >NUL 2>NUL
REM Saving values
FOR %%A IN (one two three) DO (
ECHO.Value %%A>>"!_ValuesFile!" )
)
CALL :Main
( PAUSE
ENDLOCAL
EXIT /B 0
)
:Main
FOR /L %%L IN (0,1,2) DO (
CALL SET /A "_Value=%%L + 1"
ECHO.&ECHO.------ Iteration: %%L ------&ECHO.Value number !_Value!:
IF %%L EQU 0 ( SET "_ForOptions=tokens=*" ) ELSE (
SET "_ForOptions=Skip=%%L tokens=*" )
CALL :Loop %%L
)
GOTO :EOF
:Loop
FOR /F "%_ForOptions%" %%i IN (' type "%_ValuesFile%"
') DO ( CALL SET "#value%_Value%final=%%i" )
ECHO.!#value%_Value%final!
GOTO :EOF
* Break the Loop on the First Match:
#( SETLOCAL EnableDelayedExpansion
ECHO OFF
SET "_ValuesFile=%~dp0values.txt"
REM Remove Old Values File
DEL /F /Q "!_ValuesFile!" >NUL 2>NUL
REM Saving values
FOR %%A IN (one two three) DO (
ECHO.Value %%A>>"!_ValuesFile!" )
)
CALL :Main
( PAUSE
ENDLOCAL
EXIT /B 0
)
:Main
FOR /L %%L IN (0,1,2) DO (
CALL SET /A "_Value=%%L + 1"
ECHO.&ECHO.------ Iteration: %%L ------&ECHO.Value number !_Value!:
IF %%L EQU 0 ( SET "_ForOptions=tokens=*" ) ELSE (
SET "_ForOptions=Skip=%%L tokens=*" )
CALL :Loop %%L
)
ECHO.&ECHO.------ Final Values After %%L Iterations: ------
SET #value
GOTO :EOF
:Loop
FOR /F "Tokens=*" %%A IN ('
CMD /C "FOR /F %_ForOptions% %%i IN (' type "%_ValuesFile%" ') DO #(ECHO.%%i&exit /b)"
') DO #(
SET "#value%_Value%final=%%~A"
)
ECHO.!#value%_Value%final!
GOTO :EOF
Example Output from Break the Loop Version:
Y:\>C:\Admin\S-O_Value-Checker_v2.cmd
------ Iteration: 0 ------
Value number 1:
Value one
------ Iteration: 1 ------
Value number 2:
Value two
------ Iteration: 2 ------
Value number 3:
Value three
------ Final Values After %L Iterations: ------
#value1final=Value one
#value2final=Value two
#value3final=Value three
Press any key to continue . . .
I'm trying to convert a time value from a text file from hr:min:sec.sec to just seconds. I have a file with event numbers (consecutive order, 1,2,3 etc.) in column 1 of each row and the rest of the row is event data as in my example below. I want to have the user enter two numbers, with which my script grabs the corresponding hr:min:sec of each event and converts into only seconds.
The file format is 4 000-01:04:10.983745 34.56 string1 string_2 (this would be the 4th line, its date/time, a duration in seconds, and two static strings in the next two columns.
I am using a for loop to grab tokens 1, 2, and 3 using : as the delims and then just trimming the strings for the purpose of performing arithmetic.
So %%A should be 4 000-01, %%B should be 04, and %%C should be everything else on the line. Now I just read batch doesn't support decmials, so I can do without them if needed. But this isn't returning anything:
setlocal enabledelayedexpansion enableextension
REM auto-setting event values for testing
set begin=3
set end=4
for /f "tokens=1,2,3 delims=:" %%A in ('findstr /b /c:"!begin![^0-9]" event.txt') do (
set "hr=%%A"
set /A "min=%%B"
set "sec=%%C"
set /A "hr=!hr:~-2!"
set /A "sec=!sec:~0,2!"
set /A "total=(hr*3600)+(min*60)+sec"
echo !total!>>time.txt
)
exit /B
If your file format is:
line 4 000-01:04:10.983745 34.56 string1 string_2
delim - : : .
token 1 2 3 4
var - A B C
A common technic to avoid the leading zero/octal problem is to prefix
a two place decimal with a literal 1 and subtract 100.
Set /A allows multiple calculations on a line seperated by a comma, the vars don't need to be enclosed in percent signs (doesn't apply to for/arg vars).
#Echo off
setlocal enabledelayedexpansion enableextensions
for /f "tokens=2-4 delims=-:." %%A in (
'findstr /b /C:"4 " event.txt'
) do Set /A "hr=1%%A-100,min=1%%B-100,sec=1%%C-100,total=hr*3600+min*60+sec"
echo Total is %total% (hr=%hr%, min=%min%, sec=%sec%)
echo %total% >>time.txt
exit /B
Sample output:
Total is 3850 (hr=1, min=4,sec=10)
Here is an approach that regards the fractional seconds also, rounded to six fractional figures:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=event.txt"
set "_TARGET=time.txt"
set "_REGEX=^[0-9][0-9]* [0-3][0-9][0-9]-[0-9][0-9]:[0-5][0-9]:[0-5][0-9].[0-9][0-9]* "
rem // Convert filtered lines:
> "%_TARGET%" (
for /F "tokens=1-9* delims=:.- " %%A in ('findstr /R /C:"%_REGEX%" "%_SOURCE%"') do (
rem // Extract and store hour, minute, second values:
set "HOUR=1%%C" & set "MIN=1%%D" & set "SEC=1%%E"
rem // Extract and store fractional seconds and also the static strings:
set "FRAC=1%%F0000000" & set "STR1=%%I" & set "STR2=%%J"
rem // Convert hour, minute, second values to decimal integers:
set /A "HOUR%%=100, MIN%%=100, SEC%%=100"
setlocal EnableDelayedExpansion
rem // Convert fractional seconds to decimal number:
set /A "FRAC=!FRAC:~,7!%%1000000+!FRAC:~7,1!/5"
rem // Compute integer seconds, round to 6 decimal places:
set /A "SEC+=60*(MIN+60*HOUR)+FRAC/1000000" & set "FRAC=000000!FRAC!"
rem // Rebuilt line with time value replaced by fractional seconds:
echo %%A %%B-!SEC!.!FRAC:~-6! %%G.%%H !STR1! !STR2!
endlocal
)
)
endlocal
exit /B
First of approaches, excuse me if I do not express myself well in English.
I'm debutante in batch and I need help to make a script
I articles.txt retrieves a document in which there are many lines.
some lines of my document
"T0047" ;"Tuyau 1km";"Marque2";"jardinage";"75 000";"promo"
"T00747";"Tuyau 1m";Marque2";"jardinage";"30 000";"promo"
First, I have to remove the quotation marks in the file.
It is done with:
#echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (articles.txt) do (
set a=%%a
set a=!a:"=!
echo !a!
echo !a! >>resultat.txt
)
the result
T0047 ;Tuyau 1km;Marque2;jardinage;75 000;promo
T00747;Tuyau 1m;Marque2;jardinage;30 000;promo
Then I have to perform a multiplication on a column.
For this, I have the problem that if the space is not so mutiplication realize I made a script that removes spaces.
#echo off
setlocal enabledelayedexpansion
for /F "delims=; tokens=1-8" %%a in (resultat.txt) do (
set a=%%e
set a=!a: =!
echo %%a;%%b;%%c;%%d;!a!;%%f;%%g;%%h
echo %%a;%%b;%%c;%%d;!a!;%%f;%%g;%%h >>resultat2.txt
)
the result
T0047 ;Tuyau 1km;Marque2;jardinage;75000;promo
T00747;Tuyau 1m;Marque2;jardinage;30000;promo
Then I made my multiplication.
#echo off
setlocal enabledelayedexpansion
for /F "delims=; tokens=1-8" %%a in (resultat2.txt) do (
set a=%%e
:: set /a a=!a!/0.6
set /a a=!a!*16666/10000
echo %%a;%%b;%%c;%%d;!a!;%%f;%%g;%%h
echo %%a;%%b;%%c;%%d;!a!;%%f;%%g;%%h >>resultat3.txt
)
the result
T0047 ;Tuyau 1km;Marque2;jardinage;124995;promo
T00747;Tuyau 1m;Marque2;jardinage;49998;promo
Now, i add some text just after the first colomn
set champ2=MAGASIN_1;T
for /F "delims=; tokens=1,*" %%a in (resultat3.txt) do (
echo %%a;%champ2%;%%b
echo %%a;%champ2%;%%b >>resultat_final.txt
)
The actual result is:
T0047 ;MAGASIN_1;T;Tuyau 1km;Marque2;jardinage;124995;promo
T00747;MAGASIN_1;T;Tuyau 1m;Marque2;jardinage;49998;promo
Now I would add a space so that the figure is more readable.
T0047 ;MAGASIN_1;T;Tuyau 1km;Marque2;jardinage;124 995;promo
T00747;MAGASIN_1;T;Tuyau 1m;Marque2;jardinage;49 998;promo
This is the way I would do it:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%A in (articles.txt) do (
set "a=%%A"
set a=!a:"=!
for /F "delims=; tokens=1-8" %%a in ("!a!") do (
set /A "g1=%%g*16666/10000"
set "g2="
for /L %%i in (1,1,3) do if defined g1 (
set "g2= !g1:~-3!!g2!"
set "g1=!g1:~0,-3!
)
echo %%a;%%b;%%c;%%d;%%e;%%f;!g2:~1!;%%h
echo %%a;%%b;%%c;%%d;%%e;%%f;!g2:~1!;%%h >> result.txt
)
)
articles.txt:
"T0047" ;"MAGASIN_1";"T";"Tuyau 1km";"Marque2";"jardinage";"75000";"promo"
"T00747";"MAGASIN_1";"T";"Tuyau 1m";Marque2";"jardinage";"30000";"promo"
result.txt:
T0047 ;MAGASIN_1;T;Tuyau 1km;Marque2;jardinage;124 995;promo
T00747;MAGASIN_1;T;Tuyau 1m;Marque2;jardinage;49 998;promo
Your program is good. Some tips:
Don't divide by a power of 10. Instead, remove the fractional part if you don't want it. Use *= . And to get the space in the number:
#echo off
set x=75000
set /a x *= 16666
set x=%x:~0,-4%
echo %x:~0,-3% %x:~-3%
I'll respond only to the multiplication section.
I can see nothing in your code that can possibly generte the two extra columns ;MAGASIN_1;Tand consequently, the target field 75000 and 30000 are in %%g, not %%e.
Comment : Do not use the "broken label" comment form ::comment within a block statement (a parenthesised series of statements) because it can terminate the block prematurely. Always use rem with a block.
So - modified code working on %%g
set a=%%g
rem set /a a=!a!/0.6
REM set /a a=!a!*16666/10000
set /a a=!a!*10/6
SET "a= !a:~-9,-6! !a:~-6,-3! !a:~-3!"
FOR /f "tokens=*" %%q IN ("!a!") DO SET "a=%%q"
echo %%a;%%b;%%c;%%d;%%e;%%f;!a!;%%h
Reason: Batch has a signed-32-bit limit, so if the source field is >~120000 then your calculation will generate a negative number (try 130000 for example) The revised calculation is more accurate and since intermediate results are less likely to exceed 2**31 can cope with larger values in the %%g field.
The set following the calculation changes the numeric value in a to
space(millions)space(thousands)space(units)
(The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".)
The for /f "tokens=*"... statement simply removes leading spaces from the value of a.
With the explanatin of the two additional columns, This revision should solve the "add-spaces" problem:
set a=%%e
rem set /a a=!a!/0.6
REM set /a a=!a!*16666/10000
set /a a=!a!*10/6
SET "a= !a:~-9,-6! !a:~-6,-3! !a:~-3!"
FOR /f "tokens=*" %%q IN ("!a!") DO SET "a=%%q"
echo %%a;%%b;%%c;%%d;!a!;%%f;%%g;%%h
however, if you want to skip the last step (insertion of 2 extra fields) then insert this line before the for line in the "multiplication" batch
set champ2=MAGASIN_1;T
and change the echo line in that batch to
echo %%a;%champ2%;%%b;%%c;%%d;!a!;%%f;%%g;%%h
Since you have a semicolon-delimited list of values where each item is enclosed within quotation marks, I would go for a standard for to get the items of each line and remove the enclosing quotation marks. The great advantage of this method is that it really cares about the quotation marks, so the list items may even contain semicolons on their own. The only disadvantage is that question marks and asterisks are not allowed in any of the list items:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Redirect all data to output file "resultat.txt" at once:
> "resultat.txt" (
rem Loop through all (non-empty) lines of input file "articles.txt":
for /F "usebackq delims=" %%L in ("articles.txt") do (
rem Reset list collector and loop index:
set "LIST="
set /A "INDEX=0"
rem Loop through the list items of the current line:
for %%I in (%%L) do (
rem Apply current list item with `""` removed, increment loop index:
set "ITEM=%%~I"
set /A "INDEX+=1"
rem Do numeric calculation for a certain list item:
setlocal EnableDelayedExpansion
if !INDEX! EQU 5 (
rem Convert item to a number, avoid error messages:
2> nul set /A "CALC=!ITEM!"
rem Do calculation with rounding (for negative and positive numbers):
if !CALC! LSS 0 (
set /A "CALC=(!CALC!*10-6/2)/6"
) else (
set /A "CALC=(!CALC!*10+6/2)/6"
)
rem Insert thousands separators (space) between every third digit:
set "CALC=!CALC:~-12,-9! !CALC:~-9,-6! !CALC:~-6,-3! !CALC:~-3!"
for /F "tokens=*" %%N in ("!CALC!") do (
set "ITEM=%%N"
)
)
rem Append separator (semicolon) and current item to list:
for /F delims^=^ eol^= %%S in ("!LIST!;!ITEM!") do (
endlocal
set "LIST=%%S"
)
)
rem Return built list, remove superfluous leading separator (`;`):
setlocal EnableDelayedExpansion
echo(!LIST:~1!
endlocal
)
)
endlocal
exit /B
The calculation herein incorporates rounding to the nearest integer, which works even for negative input numbers.
The newly generated list is stored into the new file resultat.txt.
Okay so here is what I have.
#echo off
setLocal EnableDelayedExpansion
:begin
set /a M=0
set /a number=0
set /p Input=You:
echo %Input% >> UIS
for /F "tokens=1 delims= " %%i in ("%Input%") do (
set /a M+=1
set i!M!=%%i
)
del UIS 1>nul 2>nul
:loop
set /a number+=1
set invar=!i%number%!
echo %invar%
pause > nul
goto loop
Say, for example, the Input string was "Lol this is my input string"
I want the for loop to set i!M! where M = 1 to "Lol", where M = 2 i!M! is "this" and where M = 3 i!M! is "is" and so on. Now, of course, this can't go on forever, so even if I have to stop when M = 25 or something, and say the string was only 23 words long. Then when M = 24 and 25 then i!M! is simply null or undefined.
Any help is appreciated, thank you.
for /f reads line by line, not word by word.
Here's an answer proposed at How to split a string in a Windows batch file? and modified for your situation:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM Set a string with an arbitrary number of substrings separated by semi colons
set teststring=Lol this is my input string
set M=0
REM Do something with each substring
:stringLOOP
REM Stop when the string is empty
if "!teststring!" EQU "" goto displayloop
for /f "delims= " %%a in ("!teststring!") do set substring=%%a
set /a M+=1
set i!M!=!substring!
REM Now strip off the leading substring
:striploop
set stripchar=!teststring:~0,1!
set teststring=!teststring:~1!
if "!teststring!" EQU "" goto stringloop
if "!stripchar!" NEQ " " goto striploop
goto stringloop
:displayloop
set /a number+=1
set invar=!i%number%!
echo %invar%
pause > nul
goto displayloop
endlocal
for /F command divide a line in a definite number of tokens that must be processed at once via different replaceable parameters (%%i, %%j, etc). Plain for command divide a line in an undefined number of words (separated by space, comma, semicolon or equal-sign) that are processed one by one in an iterative loop. This way, you just need to change this for:
for /F "tokens=1 delims= " %%i in ("%Input%") do (
by this one:
for %%i in (%Input%) do (
PS - I suggest you to write the array in the standard form, enclosing the subscript in square brackets; it is clearer this way:
set i[!M!]=%%i
or
set invar=!i[%number%]!