【问题标题】:value is void in loop in .bat [duplicate].bat 中的循环值无效 [重复]
【发布时间】:2020-11-22 05:45:23
【问题描述】:

我有这段代码,我想从当前日期减去一天,从 0 到 -10,但我只正确地获得了最后一个超出周期的值,知道为什么吗?

echo off
Setlocal EnableDelayedExpansion

FOR /L %%A IN (0,1,10) DO (
    FOR /F "usebackq tokens=*" %%t IN (`powershell -NoProfile -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"`) DO (SET "START_DATE=%%t")
    echo START_DATE: %START_DATE%
)
echo START_DATE: %START_DATE%
Endlocal



pause

PopD
exit

我在终端得到的是这个

echo off
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE: 2020/07/22 11:07:06
Presione una tecla para continuar . . .

【问题讨论】:

标签: batch-file cmd


【解决方案1】:

您没有使用已启用的delayedexpansion,但也不要使用usebackq,因为它不需要。

@echo off & Setlocal EnableDelayedExpansion

FOR /L %%A IN (0,1,10) DO (
    FOR /F "tokens=*" %%t IN ('powershell -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"') DO (
    SET "START_DATE=%%t"
    echo START_DATE: !START_DATE!
 )
)
echo START_DATE: %START_DATE% 
Endlocal
pause
popd
exit

注意! 而不是%。它告诉系统您要扩展哪个变量。

附带说明,如果您只是想echo 循环中的日期/时间,则可以不使用delayedexpansion

@echo off
FOR /L %%A IN (0,1,10) DO (
    FOR /F "tokens=*" %%t IN ('powershell -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"') DO (
    SET "START_DATE=%%t"
    echo START_DATE: %%t
 )
)
echo START_DATE: %START_DATE% 
Endlocal
pause
PopD
exit

【讨论】:

  • 非常感谢,我认为必须声明这个 SET "START DATE = %% t"
  • 嗯,不。您可以简单地使用元变量,除非您跳出循环以在其他地方使用该变量。
【解决方案2】:

这不会像 Compo 的答案那样产生一组环境变量。但是,我认为它会按照原始问题的要求进行。

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -Command ^
     "(0..-10) | ForEach-Object { (Get-Date).AddDays($_).ToString('yyyy/MM/dd') }"
@pause

【讨论】:

    【解决方案3】:

    要在cmd.exe 窗口中获得所需的输出,您根本不需要 ,只需一个

    @"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile "for($i=0; $i -le 10; $i++){"(Get-Date).AddDays(-$i).ToString('START_DATE: yyyy/MM/dd HH:mm:ss')}"
    @Pause
    

    如果您需要从 运行它,因为您需要在每一行输出上执行额外的工作,那么您应该再次允许 执行大部分繁重的工作:

    @For /F Delims^= %%G In ('^"
     "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
     "for($i=0; $i -le 10; $i++){(Get-Date).AddDays(-$i).ToString(`"^
     "'START_DATE: yyyy/MM/dd HH:mm:ss')}"^"')Do @Echo %%G
    @Pause
    

    此方法还可以扩展,以便您也可以直接将输出定义为变量,%Now[-1]%%Now[-2]%%Now[-3]% 等。这将为您提供一种简单的方法来根据几天前;例如:

    @For /F Delims^= %%G In ('^"
     "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
     "for($i=1; $i -le 10; $i++){(Get-Date).AddDays(-$i).ToString(`"^
     "\"Now[-$i]^=yyyy/MM/dd\")}"^"')Do @Set "%%G"
    @Echo %Now[-6]%&Pause
    

    最后一行显然只是为了向您展示定义的变量将输出什么。

    或者基于@lit在评论部分建议的更简单的范围方法:

    @For /F Delims^= %%G In ('^"
     "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
     "(0..-10)|%%{(Get-Date).AddDays($_).ToString(\"Now[$_]^=yyyy/MM/dd\")}"
     ^"')Do @Set "%%G"
    @Echo %Now[0]%&Pause
    

    【讨论】:

    • 使用范围会更容易。 (0..-10) | ForEach-Object { (Get-Date).AddDays($_).ToString('yyyy/MM/dd HH:MM:ss') }
    • 是的@lit,点了,但是由于问题并不是关于powershell,我的意图是表明powershell命令不需要运行十次do 10件事,而不是如何更有效地使用 powershell。我使用该方法在答案的底部添加了一个附加示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2013-10-29
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多