在批处理文件中使用 powershell 从文本文件中添加浮点数

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

我有一个文本文件记录来自 ffprobe 的一些视频文件的视频持续时间的时间戳,该文本文件如下所示:

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

我正在尝试将它们相加,因为批处理文件不允许浮点数,我选择使用 powershell。这是我的以下代码:

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%    
)

但又好像是因为它是一个浮点数我无法做类似

的事情
 SET /a total=%total% + %total%

所以我不能在这一行中将其添加为变量:

 powershell %total% + %item%

我已经尝试了所有我能想到的组合,但都没有成功,进行了大量搜索,但没有任何结果。

知道如何做到这一点,或者是否有更好的方法来纯批量添加所有这些?

所以这就是我想出的,虽然没有尽可能优雅,但它正在工作。希望它快一点,但 PowerShell 会减慢速度,但绝对值得!

做dos的时候想想都觉得很疯狂,他们从来没有想过用浮点数,哈哈

无论如何这里是代码:

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.

我希望这对某人有所帮助!有点臭我不能为这个问题问一个问题 6 个月考虑到没有我能找到的解决方案遇见我 OP

我又一次发布了我每次都尝试做的问题后的解决方案,祝你有美好的一天!

编辑:感谢@Gerhard

我已经改成了这个,但是把代码留在这里以防有人需要以不同的方式解决类似的问题。

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) 

然后保持原样,直到有人发布更好的解决方案。

Powershell 解决方案会简单得多,但鉴于您需要 batch-filepowershell:

@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%

我们只需将所有带有运算符 + 的数字附加到一个变量,然后将该变量传递给 powershell 并获得结果。 笔记! delayedexpansion 是必需的,因为我们正在设置

或者利用 powershell 完成所有工作并将结果简单地分配给变量:

@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%

你可以在一个非常简单和纯粹的批处理文件中实现这一点,运行 比任何 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%

当然,这个解决方案之所以如此简单,是因为它假设所有输入的数字都有 6 位小数!如果不是这种情况,则应相应修改代码...