'using powershell inside batch file to add floating numbers from text file

i have a text file logging timestamps from ffprobe on video durations of some video files, which that text file looks like this:

14.068700
5.043011
84.071967
5.043011
104.058600
5.043011
134.055234
5.056000 ....

I am trying to add these up, since batch files do not allow for floating numbers i chose to use powershell. here is my following code:

set total=0
for /f "tokens=*" %%x in (timestamps.txt) do (
    set item=%%x    
    echo !item!
    for /f  "delims=." %%i in ('powershell %total% + %item%') DO SET total=%%i      
    echo %total%    
)

but again it seems cause it is a floating number i am unable to do something like

 SET /a total=%total% + %total%

so that i can not add that as a variable in this line:

 powershell %total% + %item%

I have tried every combo i can think of with no luck, lots of searches and nothing comes back.

any idea how to do this or is there a better way to add up all these in pure batch ?



Solution 1:[1]

a pure Powershell solution would have been much simpler, but seeing as you require batch-file with powershell:

@echo off
setlocal enabledelayedexpansion & set nums=
for /f "usebackq delims=" %%x in ("timestamps.txt") do set nums=!nums!%%x+
for /f "delims=" %%i in ('powershell %nums:~0,-1%') do set "total=%%i"
echo Total: %total%

We just append all the numbers with the operator + to a variable, then pass that variable to powershell and get the result. Note! delayedexpansion is needed because we are setting

or by utilizing powershell to do all the work and simply assign the result to the variable:

@echo off
for /f "delims=" %%i in ('"powershell -command (Get-Content -Path "timestamps.txt" ^| Measure-Object -Sum^).Sum"') do set "total=%%i"
echo Total: %total%

Solution 2:[2]

so this is what i came up with, not as elegant as it possibly can be BUT it is working. Wish it was a bit quicker but PowerShell slows things down a bit but definitely worth it!

its crazy to think when doing dos they never thought of using floating numbers, lol

anyways here is code:

set seconds=0
set item=0
for /f "tokens=*" %%t in (%filename%_copy_two%fileextension%) do (
        set item=%%t
        for /f %%i in ('powershell !item!+!seconds!') do (set seconds=%%i) 
    )
    
for /f %%i in ('powershell -NoP "[Math]::Round(!seconds!/ 60,2)"')  do (set minutes=%%i) 

set HH=00
for /f "tokens=1 delims=." %%r in ('echo %minutes%') do set min=%%r
for /f "tokens=2 delims=." %%p in ('echo %minutes%') do set sec=%%p

IF %sec% GTR 60 (
    set /a newSec=!sec!-60
    if !newSec! lss 10 set newSec=0!newSec!
    set /a newMin=1 + !min!
    if !newMin! lss 10 set newMin=0!newMin!
    
) else (
    set /a newMin=!min!
    set /a newSec=!sec!
)

IF %newMin% LSS 60 (
    if !newMin! lss 10 set newMin=0!newMin!
    set MM=!newMin!
    if !newSec! lss 10 set newSec=0!newSec!
    set SS=!newSec!
    GOTO playlistTotal  
)

IF %newMin% GEQ 60 IF %newMin% LSS 120 (
    set /a MM=!newMin!-60
    if !MM! lss 10 set MM=0!MM!
    set /a HH=01
    set SS=!newSec!
    GOTO playlistTotal  
)

IF %newMin% GEQ 120 IF %newMin% LSS 180 (
    set /a MM=!newMin!-120
    if !MM! lss 10 set MM=0!MM! 
    set /a HH=02
    set SS=!newSec!
    GOTO playlistTotal
) 

IF %newMin% GEQ 120 IF %newMin% LSS 240 (
    set /a MM=!newMin!-180
    if !MM! lss 10 set MM=0!MM!
    set /a HH=03    
    set SS=!newSec!
    GOTO playlistTotal
) 

IF !newMin! EQU 240 (
    set /a MM=!newMin!-240
    if !MM! lss 10 set MM=0!MM!
    set /a HH=04    
    set SS=!newSec! 
    GOTO playlistTotal  
) 

IF %newMin% Gtr 240 (
    ECHO  We do not suggest a single playlist over 4 hours.
    echo  Please Go back edit your list to be shorter.
    ECHO  And just append to it
    del %filename%_copy%fileextension%
    del %filename%_copy_two%fileextension%
    GOTO editPlaylist
)


:playlistTotal
del %filename%_copy%fileextension%
del %filename%_copy_two%fileextension% 
echo.
Echo Playlist a total duration of = !HH!:!MM!:!SS!
echo.

IF !newMin! EQU 240 (
    set /a MM=!newMin!-240
    if !MM! lss 10 set MM=0!MM!
    set /a HH=04    
    set SS=!newSec! 
    GOTO playlistTotal  
) 

IF %newMin% Gtr 240 (
    ECHO  We do not suggest a single playlist over 4 hours.
    echo  Please Go back edit your list to be shorter.
    ECHO  And just append to it
    del %filename%_copy%fileextension%
    del %filename%_copy_two%fileextension%
    GOTO editPlaylist
)


:playlistTotal
del %filename%_copy%fileextension%
del %filename%_copy_two%fileextension% 
echo.
Echo Playlist has a total duration of= !HH!:!MM!:!SS!
echo.

I hope this helps someone out! kind of stinks i cant ask a question for 6 months for this question considering there is NOT solution that I can find that met me OP

And once again I posted my solution after a question which I try to do every time, have a great day!

EDIT: thanks to @Gerhard

I have changed to this, but leaving the code here in case someone needs for a similar issue in a different way.

for /f "delims=" %%i in ('"powershell -command (Get-Content -Path "%filename%_copy_two%fileextension%" ^| Measure-Object -Sum^).Sum"') do set "seconds=%%i"
for /f %%i in ('powershell -NoP "[Math]::Round(!seconds!/ 60,2)"')  do (set minutes=%%i) 

Then keeping the same as is till someone posts a better solution.

Solution 3:[3]

You can achieve this in a very simple and pure Batch file that run much faster than any PS:

@echo off
setlocal

set /A factor=1000000, total=0
for /F "tokens=1,2 delims=." %%a in (timestamps.txt) do set /A total+=%%a*factor+1%%b-factor

echo %total:~0,-6%.%total:~-6%

Of course, this solution is so simple because it assumes that all input numbers have 6 decimals! If this is not the case, then the code should be modified accordingly...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Aacini