从 For 循环中获取值的批处理脚本

Posted

技术标签:

【中文标题】从 For 循环中获取值的批处理脚本【英文标题】:Batch Script to get value from For Loop 【发布时间】:2020-11-13 01:45:28 【问题描述】:

我一直在尝试从文本文件中逐行读取。在每一行中,我在第 3 列和第 4 列中确实有“开始时间”和“结束时间”字段,如下所示。

文件1,110543,2020-07-18T03:09:12.1321687+00:00,2020-07-18T03:10:22.4097433+00:00,000001

文件2,210543,2020-07-18T04:19:28.0459100+00:00,2020-07-18T04:26:08.6626472+00:00,000002

我只想使用下面的脚本找出“开始时间”和“结束时间”列之间的区别。

@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) 值在我使用 时按预期为 line1 打印!开始时间! & !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

执行后,我收到“0 is unexpected at this time”。你能帮我解决这个问题吗

【问题讨论】:

你的代码结构我不清楚。检查括号。三个明显的要点:要处理字符串,请将其括在引号中:for /f %options% %%a in ("!starttime!") doecho command took... 行中的 ) 必须转义(^))才能不结束代码块和(格式错误的)标签在循环/代码块中是不允许的。对于 cmets,使用 REM 而不是 :: 您好斯蒂芬,感谢您的回复!括号放置正确。当我在这里复制代码时,括号列在代码块之外。因此,我只是在代码块中手动附加了括号。而且,我尝试使用“!starttime!”双引号也仍然出现相同的错误。 【参考方案1】:

您的代码中存在一些问题:

    不要使用:: 作为评论。特别是在代码块内。它可能会破坏您的代码或导致意外且难以排除故障的结果。 对于代码块中定义的所有变量,您需要 delayed expansion(您对一些变量使用了延迟扩展,但不是全部。 set /a 根本不需要%!(可选,但在这里你需要! 而不是%)。 要处理带有for /f 的字符串,它需要被引用,或者for 尝试查找具有该名称的文件。 你有一对超级流利的括号。 %csvFilePath% 未定义。 for /f %options% ... 有效,但不适用于延迟变量,因此我将 %options% 的声明移出循环。 你的代码没有正确缩进,所以结构很难辨认(我发现缩进后没有延迟扩展,这很明显)

您的代码已修复所有这些问题:

@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^)
  )
)

(注意:我没有检查你的数学 - 我相信你,因为结果似乎合理)

使用您的示例文件输出:

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)

【讨论】:

以上是关于从 For 循环中获取值的批处理脚本的主要内容,如果未能解决你的问题,请参考以下文章

在批处理脚本的for循环中重定向命令的输出

我们可以在批处理脚本的 for 循环中使用 IF 条件吗?

在PyQt脚本中使用多处理时的RuntimeError和IOError

Windows bat脚本之for循环用法

Windows bat脚本——for循环用法详解

在 Windows 批处理脚本的 for 循环中未通过“查找”命令获得所需的输出