【问题标题】:How to get current date inside a FOR loop如何在 FOR 循环中获取当前日期
【发布时间】:2021-02-04 02:08:33
【问题描述】:

我在 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

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

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

【问题讨论】:

  • echo !d! File %%i was uploaded (recommended read)。顺便说一句:如果你使用...in ('dir "C:\files\*.vib" /b /a-d /o-d') do...,你可以跳过if 命令。最好引用"c:\files\%%i" 来处理文件名中可能存在的空格。甚至更好:gsutil cp "%%~fi" ...

标签: windows for-loop batch-file cmd


【解决方案1】:

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

只需在 Dir 循环之前创建您的 DateTime 字符串 %dt%:脚本的时间当然每个都相同,但 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

如果您确实需要记录每个文件单独处理后的时间,只需直接在同一个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

[编辑 /]

以防万一您的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

出于礼貌,(我看不出你为什么不能使用 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));

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

@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

【讨论】:

  • @Compo。我的脚本工作得几乎完美,但我缺少一件事。在我有 if /i "%%~xi"==".vib" (... 之前,因为当它遇到带有 ext .vbk 的第一个文件时,它应该转到:done。没有这个,它会尝试上传它找到的所有 .vbk 文件,对吗?那么如何使用 robocopy 将其添加到您的代码中?我认为它应该在每个 gsutil cmd 之前,但我可能必须将 %%~xi 替换为您使用的内容...我尝试了 %%~xG,因为 %%G 在 FOR 循环中,但这不起作用。如何仅获取文件名 ext?可以 cp 所有 .vbk 和 .vib,但我只需要一个 .vbk。
  • 看起来 ..~xi 是正确的,但我认为前面的 %% 是错误的。我只需要 IF 语句来检查它在文件夹中找到的每个文件的文件扩展名,我不知道 %% 是什么意思或为什么它在您的代码示例中不起作用。
  • @yorkman,在你的问题中没有提到任何.vbk 文件,或者任何后续的 cmets。您现在提出的问题与您发布的问题完全不同,IMO,我已经彻底处理了这些问题。我发布的代码基于您自己的代码,并非旨在接触.vbk 文件,因此根本不会对它们做任何事情,也不会受到它们的影响。根据我对您现在所问内容的理解,我在答案的底部添加了另一个示例。但是请不要要求我进行更多更改,我相信我现在已经完成了您的问题。
  • 我使用什么扩展并不重要。关键是它应该取决于 IF 语句中的扩展,就像您在 FOR 循环中一样,但您没有在代码中包含 IF 语句。在我最初的问题中,我有 .vib,因为这只是一个例子。我处理的另外两个是.vbk 和.vbm。无论如何,就像您说的那样,您帮了我很多忙,对于造成的误解,我深表歉意。你应该得到充分的信任,然后是一些,所以你去吧!
  • @yorkman,我最初没有包含If 声明,因为我不需要,而且你没有告诉任何人你正在使用多个扩展!请打开命令提示符窗口,输入dir /?,然后按[ENTER] 键,阅读我使用的Dir 命令的简单用法。它应该告诉您,针对*.vib 的全局,它只会列出这些文件。当它只列出.vib 文件时,If 语句将是多余的。我的新修改使用*.vib *.vbk,令人惊讶的是,它使用这两个扩展名返回项目,因此可以并且确实使用If 语句。
猜你喜欢
  • 2013-09-06
  • 2023-01-23
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2015-09-14
  • 2020-12-18
  • 2013-02-03
  • 1970-01-01
相关资源
最近更新 更多