i try to add two numbers received from a file.
But it shows only the last value of sum. Thx for the help!
#FOR /F "eol=; tokens=1-3 delims=, " %%i IN (test.txt) DO (
set m=%%j
set n=%%k
set /a sum=%m%+%n%
echo sum = %sum%
)
and in the test.txt i have
alex 4 5
john 6 7
and i want to see
sum=9
sum=13
it only shows
sum=13
sum=13
The problem is the percent expanding in the line set /a sum=%m%+%n% and echo sum = %sum%.
These are expanded before the FOR-loop is executed.
Therefore you got the result of the "global" set of sum.
It's better to use the delayed expansion, as then all variables enclosed with ! are expanded at runtime not parsetime
#echo off
setlocal EnableDelayedExpansion
FOR /F "eol=; tokens=1-3 delims=, " %%i IN (test.txt) DO (
set m=%%j
set n=%%k
set /a sum=m+n
echo sum = !sum!
)
Related
I'm learning windows batch-file script and creating my own scripts to practice the coding but kind of hit a block while try find whether the numbers in a text file is in sequence or not.I have two files,one file(file.txt) contains the number of lines in file_received.txt. The file_received.txt content is below:
1021
1022
1023
1024
1025
1027
1028
I'm building a script to test whether all the numbers in the text file are in sequence .so as a first step I'm trying to extract each line of the file_received to be assigned to a variable through if / for loop but the if command loop assigning all the lines to the variable num from file_received.txt at the same time. Is it possible to assign first line of the file to variable num and increment it as the if loops increment?
setlocal EnableDelayedExpansion
rem assign the number of lines to a variable
set /P var=<C:\files.txt
for /F "tokens=1" %%a in ("%var%") do echo.%%a
rem assign the first variable to var1
set /P var1=<C:\files_received_sequence.txt
for /F "tokens=1" %%a in ("%var1%") do echo.%%a
set /a x=1
:while
if %x% leq %var% (
echo %x%
rem assigning each line to the variable num inside the if loop and will be used in comparison and reser
for /F "tokens=%x%" %%i in (C:\files_received.txt) do set num=%%i
echo %num%
set /a x+=1
goto :while
)
echo test :D
the output is as below in loop 1 the entire file content is assigned to the variable num and from loop 2 to 7 the last number is assigned.
C:\>setlocal EnableDelayedExpansion
C:\>set /P var= 0<C:\files.txt
C:\>for /F "tokens=1" %a in ("7 ") do echo.%a
C:\>echo.7
7
C:\>set /P var1= 0<C:\files_received.txt
C:\>for /F "tokens=1" %a in ("1021") do echo.%a
C:\>echo.1021
1021
C:\>set /a x=1
C:\>if 1 LEQ 7 (
echo 1
for /F "tokens=1" %i in (C:\files_received.txt) do set num=%i
echo
set /a x+=1
goto :while
)
1
C:\>set num=1021
C:\>set num=1022
C:\>set num=1023
C:\>set num=1024
C:\>set num=1025
C:\>set num=1027
C:\>set num=1028
ECHO is on.
C:\>if 2 LEQ 7 (
echo 2
for /F "tokens=2" %i in (C:\files_received.txt) do set num=%i
echo 1028
set /a x+=1
goto :while
)
2
1028
Here's the logic I'd use to test that each number is in sequence incrementing by one (and only one) each time:
#Echo off & Setlocal EnableDelayedExpansion
Set "ln="
For /F "Delims=" %%i in (C:\file_received.txt) Do (
If Not "!ln!"=="" For /F "UseBackQ Delims=" %%v in (`"Set /A Nx=!ln!+1"`) Do (If Not "%%i"=="%%v" (Echo/OoS:!ln!/%%i & Goto :False))2> Nul
Set "ln=%%i"
)
Echo/True
Exit /B 0
:False
Echo/False
Exit /B 1
Here is a version that will highlight the item not in sequence. Do note, that it will test sequence only, in other words ensure the previous result is lower than the next
#echo off & setlocal enabledelayedexpansion
set rev=-1
for /f "delims=" %%a in (files_received.txt) do for %%i in (%%a) do (
if %%i leq !rev! (
echo %%i Out of sequence
) else (
echo %%i
set rev=%%i
)
)
besides you don't use delayed expansion (although you have enabled it), your logic is far too complicated:
#echo off
setlocal enabledelayedexpansion
set last=-1
for /f %%a in (t.txt) do (
if %%a lss !last! (
echo not in sequence
goto :eof
)
set "last=%%a"
)
echo all in sequence.
the variable !last! holds the value from the previous iteration of the loop.
(Depending on your needs, you may want to replace lss with leq)
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.
I have a file with this output:
ANS8000I Server command: 'ru FailedReport'
Unnamed[1]
------------
9
Unnamed[1]
------------
110
Unnamed[1]
------------
101
I need to take those numbers, and assign it to three different variables. I made this script, but I can't make it to work... I always got "0" as result.
#echo off
setlocal enableextensions enabledelayedexpansion
set /A counter=0
SET /A failed=0
SET /A completed=0
SET /A total=0
for /F "tokens=1 skip=4" %%a in (C:\Users\Desktop\Aux.txt) do (
if "%counter%" EQU 5 (set /A failed=%%a)
if "%counter%" EQU 9 (set /A completed=%%a)
if "%counter%" EQU 13 (set /A total=%%a)
set /A counter+=1
)
echo "Failed: " %failed% >> C:\Users\Desktop\Result.txt
echo "Completed: " %completed% >> C:\Users\Desktop\Result.txt
echo "Total: " %total% >> C:\Users\Desktop\Result.txt
Could anyone help me with this? I tried a lot of combinations (variables with !, %, %%), but I still got the same result.
Thanks!!!
#ECHO OFF
setlocal enableextensions enabledelayedexpansion
set /A counter=0
SET /A failed=0
SET /A completed=0
SET /A total=0
for /F "tokens=1" %%a in (q24152955.txt) do (
ECHO !counter! %%a
if !counter! EQU 3 (set /A failed=%%a)
if !counter! EQU 9 (set /A completed=%%a)
if !counter! EQU 6 (set /A total=%%a)
set /A counter+=1
)
echo "Failed: " %failed%
echo "Completed: " %completed%
echo "Total: " %total%
GOTO :eof
I used a file named q24152955.txt containing your data for my testing.
In delayedexpansion mode, %var% refers to the original value of var - before the loop began execution and !var! is the dynamic value - as it changes.
"something" is never going to be equal to something because the quotes are significant. Quoted values are often used in this context in case the value itself is empty or contains special characters (especially spaces) - "" is a non-empty string.
for /f ignores empty lines. I've included a superfluous echo command to show which lines the for processes. Note that the value of counter is thus the sequential number of non-empty lines in the file, not the actual line number. Note also that a line containing just one (or more) spaces is not an empty line!
#ECHO off&cls
setlocal enabledelayedexpansion
set "$count=1"
for /f "delims=" %%a in (C:\Users\Desktop\Aux.txt) do (
if !$count!==4 set failed=%%a
if !$count!==7 set completed=%%a
if !$count!==10 set total=%%a
set /a $count+=1
)
(echo Failed : %failed: =%
echo Completed : %completed: =%
echo Total : %total: =%)> C:\Users\Desktop\Result.txt
I`m having issues with a batch file I have written to process a large amount of .wav music files with a tool. The encoded format is to have loop start and end points encoded within it.
#echo off
#echo -------CONVERSION---------
for /f "tokens=1-5" %%l in (test.txt) do (
#echo %%n.wavを%%ni.fcoへ変換中です
#echo %%o %%p
set /a endloop1=%%o
set /a endloop2=%%p
set /a endloop=endloop1+endloop2
#echo %endloop1% %endloop2% %endloop%
contool -e -br 144 -loop %endloop1% %endloop% ed%%n.wav ed%%n.fco
And the test.txt file I`m reading values from in its entirety is
bgmtbl BGM_Title 7552 73664 4997136
bgmtbl BGM_GameOver 7534 22464 4014400
bgmtbl BGM_Midtown 7101 773184 3718720
bgmtbl BGM_Cross_1 7102 112838 5827154
Where the fourth and fifth values are the ones I need - the loop start point and loop length
for some reason the endloop values use the numbers from the last line of the text file over and over! e.g
7552.wavを7552i.fcoへ変換中です
73664 4997136
112838 5827154 5939992
your parametter doesn't satisfy under the condition
0<= loopstart(112838) <= loopend(5939992) < Total Sample(5118208) element=0/1
7534.wavを7534i.fcoへ変換中です
22464 4014400
112838 5827154 5939992
your parametter doesn't satisfy under the condition
0<= loopstart(112838) <= loopend(5939992) < Total Sample(4125696) element=0/1
etc
Please help, this is very perplexing!
Another possibility:
#echo off &setlocal
for /f "tokens=1-5" %%l in (test.txt) do (
echo %%n.wavを%%ni.fcoへ変換中です
echo %%o %%p
set /a endloop1=%%o
set /a endloop2=%%p
set /a endloop=%%o+%%p
)
echo %endloop1% %endloop2% %endloop%
Here you do not need delayed expansion. The first access to the %variables% is after the end of the for code block.
#echo off
#echo -------CONVERSION---------
setlocal enableDelayedExpansion
for /f "tokens=1-5" %%l in (test.txt) do (
#echo %%n.wavを%%ni.fcoへ変換中です
#echo %%o %%p
set /a endloop1=%%o
set /a endloop2=%%p
set /a endloop=!endloop1!+!endloop2!
#echo !endloop1! !endloop2! !endloop!
contool -e -br 144 -loop !endloop1! !endloop! ed%%n.wav ed%%n.fco
)
More info : http://www.robvanderwoude.com/variableexpansion.php
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%]!