如何在 FOR 循环中获取当前日期

yor*_*man 0 windows for-loop cmd batch-file

我在 C:\myscript.bat 中有以下代码示例

for /f %%i in ('dir "C:\files" /b /a-d /o-d') do (
if /i "%%~xi"==".vib" (
gsutil cp c:\files\%%i gs://mybucket
call :GetDate
echo %dt% File %%i was uploaded )
)
:done

:GetDate
set X=
for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
set DATE.YEAR=%X:~0,4%&set DATE.MONTH=%X:~4,2%&set DATE.DAY=%X:~6,2%&set DATE.HOUR=%X:~8,2%&set DATE.MINUTE=%X:~10,2%&set DATE.SECOND=%X:~12,2%
set dt=%DATE.MONTH%-%DATE.DAY%-%DATE.YEAR%_%DATE.HOUR%-%DATE.MINUTE%-%DATE.SECOND%
exit /b
Run Code Online (Sandbox Code Playgroud)

我的问题是在 FOR 循环内调用 GetDT 时在“echo %dt% File %%i was updated”中获取当前日期。只要我在 FOR 循环之外调用 :GetDate ,它就可以正常工作。我已经花了大约 4 个多小时,似乎无法让它在 FOR 循环中打印“当前”日期而不会出现某种错误。

我还尝试将整个日期代码从 :GetDate 扔到 FOR 循环中,但这也不起作用。我想它不喜欢 FOR 循环中的 FOR 循环。您的帮助将不胜感激。

Com*_*mpo 6

我认为没有必要延迟扩张。

只需%dt%Dir循环之前创建您的 DateTime string :脚本的时间当然对每个都相同,但 IMO 每个单独gsutil命令结束的确切时间不应该是关键任务,批处理运行时间应该是。

@Echo Off
SetLocal EnableExtensions
Set "sd=C:\files"
Set "fg=*.vib"
For /F EOL^=L %%G In ('%SystemRoot%\System32\wbem\WMIC.exe OS GET LocalDateTime'
) Do For %%H In (%%~nG) Do Set "dt=%%H"
Set "dt=%dt:~4,2%-%dt:~6,2%-%dt:~,4%_%dt:~8,2%-%dt:~10,2%-%dt:~-2%"
For /F "EOL=? Delims=" %%G In ('Dir "%sd%\%fg%" /B /A:-D /O-D 2^> NUL') Do (
    gsutil.exe cp "%sd%\%%G" "gs://mybucket"
    Echo %dt% file %%G was uploaded)
Pause
GoTo :EOF
Run Code Online (Sandbox Code Playgroud)

如果您确实需要在单独处理每个文件后记录时间,只需直接在同一个for循环中进行:

@Echo Off
SetLocal EnableExtensions
Set "sd=C:\files"
Set "fg=*.vib"
For /F %%G In ('Dir "%sd%\%fg%" /B /A:-D /O-D 2^> NUL') Do (
    gsutil.exe cp "%sd%\%%G" "gs://mybucket" && (
        For /F "Tokens=1-6 Delims=/: " %%H In (
            '%SystemRoot%\System32\Robocopy.exe \: . /NJH /L ^
             ^| %SystemRoot%\System32\find.exe " 123"') Do (
            Echo %%I-%%J-%%H_%%K-%%L-%%M file %%G was uploaded)))
Pause
GoTo :EOF
Run Code Online (Sandbox Code Playgroud)

[编辑 /]

以防万一您gsutil没有携带.exe扩展名并且期望它返回0成功的错误级别,cp这里是对相同代码的轻微修改。

@Echo Off
SetLocal EnableExtensions
Set "sd=C:\files"
Set "fg=*.vib"
For /F %%G In ('Dir "%sd%\%fg%" /B /A:-D /O-D 2^> NUL') Do (
    gsutil cp "%sd%\%%G" "gs://mybucket"
    If Not ErrorLevel 1 For /F "Tokens=1-6 Delims=/: " %%H In (
        '%SystemRoot%\System32\Robocopy.exe \: . /NJH /L ^
         ^| %SystemRoot%\System32\find.exe " 123"') Do (
        Echo %%I-%%J-%%H_%%K-%%L-%%M file %%G was uploaded))
Pause
GoTo :EOF
Run Code Online (Sandbox Code Playgroud)

出于礼貌,(我看不出为什么您不能使用 Robocopy.exe),这里有一个版本,它cscript.exe用于通过 JScript 生成您的日期时间戳。

@if (@X) == (@Y) @end /*
@Echo Off
SetLocal EnableExtensions
Set "sd=C:\files"
Set "fg=*.vib"
For /F %%G In ('Dir "%sd%\%fg%" /B /A:-D /O-D 2^> NUL') Do (
    gsutil cp "%sd%\%%G" "gs://mybucket"
    If Not ErrorLevel 1 For /F %%H In (
        '%SystemRoot%\System32\cscript.exe /NoLogo /E:JScript "%~f0"') Do (
        Echo %%H file %%G was uploaded))
Pause
GoTo :EOF */
var d = new Date();
WScript.Echo (("0" + (d.getMonth() + 1)).slice(-2) + "-" +
  ("0" + d.getDate()).slice(-2) + "-" + d.getFullYear() + "_" +
  ("0" + d.getHours()).slice(-2) + "-" + 
  ("0" + d.getMinutes()).slice(-2) + "-" + ("0" + d.getSeconds()).slice(-2));
Run Code Online (Sandbox Code Playgroud)

[Edit2 /] 基于新的问题标准,在下面的评论中

@Echo Off
SetLocal EnableExtensions
Set "sd=C:\files"
Set "fg=*.vib *.vbk"
PushD "%sd%" 2> NUL || GoTo :EOF
For /F %%G In ('Dir %fg% /B /A:-D /O-D 2^> NUL') Do (
    If /I "%%~xG" == ".vbk" GoTo Done
    gsutil cp "%%G" "gs://mybucket"
    If Not ErrorLevel 1 For /F "Tokens=1-6 Delims=/: " %%H In (
        '%SystemRoot%\System32\Robocopy.exe \: . /NJH /L ^
         ^| %SystemRoot%\System32\find.exe " 123"') Do (
        Echo %%I-%%J-%%H_%%K-%%L-%%M file %%G was uploaded))
:Done
PopD
Pause
GoTo :EOF
Run Code Online (Sandbox Code Playgroud)