Total of array in batch - arrays

I am trying to get an average of an array in this code:
set /a arr[%b%]=%i%
where the %b% is set from 0 and b=b+1 and loops until it hits a number. The numbers in this array could vary.
Now I need to get an average of this arr[%b%] so I can display it at the end of the whole code.
Thank you

You'll need to modify this based on the size of the array:
setlocal enabledelayedexpansion
set limit=10
set /a total=0
for /l %%a in (0, 1, %limit%) do set /a total+=!arr[%%a]!
set /a ave=%total%/%limit%
Echo Total: %total%
Echo Average: %ave%
And that should work for arr[0] to arr[10].

Monacraft answer is not bad ,but I prefer to calculate the array length.Here is a revised answer (plus added modulus)...
#echo off
setlocal enabledelayedexpansion
::::::::just a test array::::::::::::
set /a arr[1]=1
set /a arr[2]=1
set /a arr[3]=1
set /a arr[4]=7
set /a arr[5]=2
set /a arr[6]=1
:::::::::::::::::::::::::::::::::::::
set /a total=0
for /f "delims=" %%# in ('set arr[^|find /c "="') do set "limit=%%#"
for /l %%a in (0, 1, %limit%) do set /a total+=!arr[%%a]!
set /a ave=total/limit
set /a mod=total%%limit
Echo Total: %total%
Echo Average: %ave%.%mod%
Echo Average(no mod): %ave%
endlocal

Related

Windows Batch: How do you call a variable with concentric variable names and exclamation marks?

I would like to call variables that contain other variables in their name when I have enabledelayedexpension so I would have concentric exclamation points in my variable call.
I apologize for the unclear wording; I'm not very familiar with this subject.
Here's a portion of my code that shows my issue:
set /a Freq[%%z]value[!value!]+=%%y
echo Freq %%z value !value! is !Freq[%%z]value[!value!]!
As is, batch interprets !Freq[%%z]value[!value!]! broken up into different variables with the !'s, and I don't think I can use %'s instead because I'm in a for loop where this variable is changing. I don't think I can use another for loop to replace !value! with a %%a either.
Here's a more complete look at my code:
set /a line=0
set /a goodLine=0
FOR /F "tokens=* delims=" %%x in (%file%) DO (
set /a line+=1
echo Line is !line!
set data[!line!]=%%x
set /a value=0
set /a checkGood=0
FOR %%y in (%%x) DO (
set /a value+=1
if !value!==1 (
set /a Freq=%%y
set /a checkFreq=%%y %% 10
if !checkFreq!==0 (
set /a checkGood=1
) else (echo bad)
) else (
if !checkGood!==1 (
for /l %%z in (40, 10, 330) do (
if !Freq!==%%z (
set /a Freq[%%z]value[!value!]+=%%y
echo Freq %%z value !value! is !Freq[%%z]value[!value!]!
set /a Freq[%%z]quantity[!value!]+=1
echo Freq %%z value !value! quantity is !Freq[%%z]quantity[!value!]!
)
)
) else (echo checkGood bad)
)
)
)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET /a value=4
FOR /L %%z IN (1,1,5) DO set /a Freq[%%z]value[!value!]=%%z+10
SET Freq
ECHO ========================
FOR %%y IN (2,7) DO FOR /L %%z IN (1,1,5) DO (
set /a Freq[%%z]value[!value!]+=%%y
SET Freq[%%z]value[!value!]
CALL echo Freq %%z value !value! is %%Freq[%%z]value[!value!]%%
)
GOTO :EOF
Or you could use a for/f "tokens=2delims==" %%e in ('set Freq[%%z]value[!value!]') do echo %%e
depends on what you really want to do.

Batch Script to get value from For Loop

I've been trying to read line by line from text file. In each line, I do have "starttime" & "endtime" field in 3 & 4 th column as I highlighted below.
File1,110543,2020-07-18T03:09:12.1321687+00:00,2020-07-18T03:10:22.4097433+00:00,000001
File2,210543,2020-07-18T04:19:28.0459100+00:00,2020-07-18T04:26:08.6626472+00:00,000002
I just want to find the difference between "starttime" & "endtime" column using below script.
#Echo off&Setlocal EnableExtensions EnableDelayedExpansion
IF EXIST "%csvFilePath%tempfile.txt" (
( for /f "tokens=1-5 delims=," %%A in (%csvFilePath%tempfile.txt) do (
echo fileRecord %%A,%%B,%%C,%%D,%%E
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%C") Do (
set starttime=%%b:%%c:%%d
)
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%D") Do (
set endtime=%%b:%%c:%%d
)
echo !starttime!
echo !endtime!
set options="tokens=1-4 delims=:.,"
for /f %options% %%a in (!starttime!) do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in (!endtime!) do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1
set /a hours=%end_h%-%start_h%
set /a mins=%end_m%-%start_m%
set /a secs=%end_s%-%start_s%
set /a ms=%end_ms%-%start_ms%
if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms%
if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs%
if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins%
if %hours% lss 0 set /a hours = 24%hours%
if 1%ms% lss 100 set ms=0%ms%
:: Mission accomplished
set /a totalsecs = %hours%*3600 + %mins%*60 + %secs%
echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total))))
start(03:09:12) & endtime(03:10:22) value is being printed for line1 as expected when I'm using !starttime! & !endtime!. I'm trying to pass the same variable to calculate the difference in below line.
for /f %options% %%a in (!starttime!) do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in (!endtime!) do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1
after execution, I'm getting "0 was unexpected at this time". Can you pls help me on this
There are some issues in your code:
don't use :: as a comment. Especially within a code block. It might break your code or lead to unexpected and hard to troubleshoot results.
you need delayed expansion for all variables defined in the code block (you used delayed expansion for a few variables, but not for all.
set /a doesn't need % or ! at all (optional, but here you'd need ! instead of %).
to process a string with for /f, it needs to be quoted, or for tries to find a file with that name.
You had a superfluent pair of parentheses.
%csvFilePath% is not defined.
for /f %options% ... works, but not with delayed variables, so I moved the declaration of %options% out of the loop.
Your code was not properly indented, so the structure was hardly recognizable (I spotted the lack of delayed expansion only after indenting, which made it blatantly obvious)
Your code with all those issues fixed:
#Echo off
Setlocal EnableExtensions EnableDelayedExpansion
set "options=tokens=1-4 delims=:.,"
IF EXIST "%csvFilePath%tempfile.txt" (
for /f "tokens=1-5 delims=," %%A in (%csvFilePath%tempfile.txt) do (
echo fileRecord %%A,%%B,%%C,%%D,%%E
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%C") Do set starttime=%%b:%%c:%%d
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%D") Do set endtime=%%b:%%c:%%d
echo !starttime!
echo !endtime!
for /f "%options%" %%a in ("!starttime!") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f "%options%" %%a in ("!endtime!") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1
set /a hours=end_h-start_h
set /a mins=end_m-start_m
set /a secs=end_s-start_s
set /a ms=end_ms-start_ms
if !ms! lss 0 set /a secs = secs - 1 & set /a ms = 100!ms!
if !secs! lss 0 set /a mins = mins - 1 & set /a secs = 60!secs!
if !mins! lss 0 set /a hours = hours - 1 & set /a mins = 60!mins!
if !hours! lss 0 set /a hours = 24!hours!
if 1!ms! lss 100 set ms=0!ms!
REM Mission accomplished
set /a totalsecs = hours*3600 + mins*60 + secs
echo command took !hours!:!mins!:!secs!.!ms! (!totalsecs!.!ms!s total^)
)
)
(Note: I didn't check your math - I trust you there, as the results seem plausible)
Output with your example file:
fileRecord File1,110543,2020-07-18T03:09:12.1321687+00:00,2020-07-18T03:10:22.4097433+00:00,000001
03:09:12
03:10:22
command took 0:1:10.00 (70.00s total)
fileRecord File2,210543,2020-07-18T04:19:28.0459100+00:00,2020-07-18T04:26:08.6626472+00:00,000002
04:19:28
04:26:08
command took 0:6:40.00 (400.00s total)

Batch File Counter in a for loop

I have a for loop that I'm trying to count each loop however this loop echo's zeros. How do I get it to increment?
#echo off
setlocal enableextensions
set /a count = 0
for /f "Delims=" %%a in (content\docs.html) do (
set /a count+=1
echo %count%
)
#echo off
setlocal enabledelayedexpansion
set /a count = 0
for /f "Delims=" %%a in (content\docs.html) do (
set /a count+=1
echo !count!
)
notice the ! instead of %. that's the consequence of using setlocal enabledelayedexpansion.

Batch script - Adding variable value to same variable

I'm trying to do something like this, but I can't make it to work.
for /F "tokens=1" %%a in (C:\Auxiliar4.txt) do (
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
)
set /A counter=0
set /A failedday=%failedday%+%failed%
if %total% NEQ 0 (set /A success=(%completed%*100)/%total%)
My problem is with these two lines:
set /A failedday=%failedday%+%failed%
if %total% NEQ 0 (set /A success=(%completed%*100)/%total%)
The first issue is with variable "failedday", I need to read numeric values from a txt file, assign them to those variables (failed, completed, total) and then assign the value of "failed" to "failedday". Then another FOR loop starts to read a different txt with same format, assign those numeric values to "failed", "completed", "total" again (losing the previous values), and add new value of "failed" to "failedday" keeping the previous addition (example, filedday=2 after first "for", after second should be failedday=2 + New"Failed"Value).
The second issue is with "IF" structure. I need to calculate the average of completed transactions taking values from "For" loop, only if "total" is not equal to 0 (to avoid divide by zero), but when I add this line my script crashes.
Could anyone help me with this? Thanks!!!
Here's a previous StackOverflow question that asks the same sort of thing.
Here's another reference for doing arithmetic with DOS Batch files.
You need to enable delayed expansion to perform the arithmetic:
#echo off & setlocal EnableDelayedExpansion
set /A failed=0
set /A completed=0
set /A total=0
for /F "tokens=1" %%a in (C:\Temp\test.txt) do (
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%
set /A counter=0
set /A failedday=failedday+failed
if total NEQ 0 (set /A success=completed*100/total)
echo Success: %success%

How do I concatenate the value of a variable into the name of another in a batch file?

So I've been writing a batch file which backs up a certain file while cleaning old entries every so often. I've run into an issue where it would be simpler and more readable to store month lengths (for calculation purpose) (days1,days2,days3,etc.), and reference these by concatenating the word days with a variable which stores the month (1, 2, 3, etc.). Unfortunately, this never seems to reference the right variable correctly. Here's the relevant code, from a section calculating a date 28 days previously:
set days1=31
set days2=28
set days3=31
set days4=30
set days5=31
(etc.)
...
set pastmonthday=%curday%-28
set pastmonthmonth=%curmonth%
set pastmonthyear=%curyear%
if %pastmonthday% lss 0 (
set /a pastmonthmonth=%pastmonthmonth%-1
set /a pastmonthprevmon=1
)
if %pastmonthmonth%==0 (
set /a pastmonthyear-=1
set /a pastmonthmonth=12
)
set monthlengthvar=0
setlocal EnableDelayedExpansion
set tempmonthlengthvar=0
if %pastmonthday% lss 0 (set tempmonthlengthvar = !days%pastmonthmonth%!)
echo.%tempmonthlengthvar%
pause
for /F "delims=" %%A in (!tempmonthlengthvar!) DO (
endlocal
set "monthlengthvar=%%A"
)
set pastmonthday+=%monthlengthvar%
echo.%pastmonthday%
pause
...
The two echoes output 0 and -7, respectively. I can't figure out why this is, no matter how I've reworked it.
some errors (forgotten /a in set, quotes etc.)
#ECHO OFF &SETLOCAL disableDelayedExpansion
SET /a days1=31
set /a days2=28
set /a days3=31
set /a days4=30
set /a days5=31
set /a pastmonthday=22-28
set /a pastmonthmonth=2
set /a pastmonthyear=2014
if %pastmonthday% lss 0 (
set /a pastmonthmonth-=1
set /a pastmonthprevmon=1
)
if %pastmonthmonth% equ 0 (
set /a pastmonthyear-=1
set /a pastmonthmonth=12
)
set /a monthlengthvar=0
setlocal EnableDelayedExpansion
set /a tempmonthlengthvar=0
if %pastmonthday% lss 0 SET /a tempmonthlengthvar=!days%pastmonthmonth%!
ECHO(%tempmonthlengthvar%
for /F "delims=" %%A in ("%tempmonthlengthvar%") DO (
IF "!"=="" endlocal
set /a monthlengthvar=%%A
)
set /a pastmonthday+=monthlengthvar
ECHO(%pastmonthday%

Resources