【问题标题】:What wrong with this batch command in Windows?Windows 中的这个批处理命令有什么问题?
【发布时间】:2011-09-20 03:56:57
【问题描述】:
FOR %%F IN (E:\backups\7DbBackup_local\*.bak) DO IF %%~tF == (time /t) echo %%F

如果修改日期的年/月/日等于当前年/月/日,则应该打印文件名

【问题讨论】:

  • 好吧,它只是在 DO 之后打印所有内容,关键是我什至不知道如何获取 IF 条件的当前日期,所以我使用基本的 cmd 命令,这显然不能以这种方式工作
  • 如果它打印do 之后的所有内容,则使用@ 为命令添加前缀或使用echo off

标签: batch-file cmd


【解决方案1】:

%%~t 为您提供日期文件的时间,大致如下:

23/03/2011 04:27 PM

但即使是 this 也可能是特定于语言环境的。

另一方面,time /t 给你03:57 PMdate /t 给你Wed 22/06/2011两者都没有作为匹配有用。

如果您希望能够匹配它们,则必须使用一些字符串技巧来仅从 %%~t(去掉时间)和 date /t(去掉日期名称)获取日期。

或者你可以省去麻烦,忘记我喜欢称之为 cmd-gymnastics 的奇怪活动,并使用一个像样的find 实用程序,或者通过下载CygWin 或使用更轻量级的GnuWin32 工具(搜索对于 FindUtils)。


如果你必须使用cmd,你可以从以下开始:

@setlocal enableextensions enabledelayedexpansion
@echo off

rem Get todays date

for /f "tokens=1,2,*" %%a in ('date /t') do set today=%%b
echo %today%

rem Process each file in turn.

for %%a IN (.\*) do call :procFile "%%a" %%~ta

endlocal
goto :eof

:procFile
    if %2==%today% echo %2 %1
    goto :eof

但请记住,如果您的语言环境信息发生更改,这可能会中断。几年前我写了一个脚本,绕过这些程序,使用 WMI 获取更准确的信息:

for /f "skip=2 tokens=2-7 delims=," %%A in ('wmic path win32_localtime get day^,hour^,minute^,month^,second^,year^ /format:csv') do (
    set /a mydate = 10000 * %%F + 100 * %%D + %%A
    set /a mytime = 10000 * %%B + 100 * %%C + %%E
)
set mydate=00000000%mydate%
set mydate=%mydate:~-8%
set mytime=000000%mytime%
set mytime=%mytime:~-6%

这会为您提供YYYYMMDDHHMMSS 格式的日期和时间,但您可以对其进行调整以提供其他值。

【讨论】:

  • l33t.... 以前从未见过这样的事情。感谢您抽出宝贵时间帮助我解决这个我不知道的主题////
  • ECHO %DATE% 显示与DATE /T 相同,表示可以从%DATE% 中提取日期。因此,它可能不是 FOR 循环,而是 SET today=%DATE:~4%
  • 嗯,我的意思是,当然,第一个脚本中的第一个 FOR 循环,初始化 today 的那个(只是想清楚一点)。
【解决方案2】:

正如 paxdiablo 所指出的,在 bat 中使用时间是特定于语言环境的。但这不是你的问题。您的问题是,在 Windows 中,您无法直接与命令的结果进行比较。

如果您想知道,顺便说一句,您既不能比较,也不能分配,也不能做任何其他事情。您需要使用 FOR 命令捕获结果,将其分配给环境变量,然后使用它。

因此您需要与 %date% 环境变量进行比较。这也是特定于语言环境的。 ~t 和 %date% 都使用相同的语言环境,因此您需要在执行命令之前将语言环境更改为能够很好地满足您的需求的通用格式,并在最后将其恢复。

试试这个...

setlocal enabledelayedexpansion
reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy-MM-dd" /f >nul
FOR %%F IN (E:\backups\7DbBackup_local\*.bak) DO (
  set dt=%%~tF
  set dt=!dt:~0,10!
  if !dt!==%date% echo %%F %%~tF !dt!
)
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul

【讨论】:

  • 我不工作,可能是因为 %date% 返回 Day Name abbr ie。周三?
  • 这取决于您的语言环境,如果它不符合您的需要,请在运行 bat 文件之前对其进行更改,如最后几行所示。我正在编辑一个更好的例子的答案。
  • 感谢您的解决方案,但@paxdiablo 的解决方案无需修改注册表即可工作。
【解决方案3】:

如果您不关心语言环境,您可以让xcopy 为您执行此操作:

xcopy E:\backups\7DbBackup_local\*.bak %tmp% /d:%date:~4,10% /l
  • %tmp% 是您的临时目录; xcopy 需要一个目的地,即使不复制也是如此。
  • %date% 提供与 date /t 相同的输出,但无需执行 for 的歌舞。
  • %date:~4,10% 使用batch substrings 获取日期mm/dd/yyyy 格式。
  • /d 告诉 xcopy 在给定日期或之后更改文件。
  • /l 告诉 xcopy 只列出要复制的文件。

【讨论】:

  • 它可能应该是%date:~4,10% 而不是%date:~5,10%(它是一个偏移量,所以它是从0 开始的)。
  • 我需要基于for循环压缩文件。使用你的方法将迫使我创建另一个批次。
  • @eugeneK;或者,只需在 for 循环中使用此命令来驱动要压缩的文件列表。
  • 这个版本也依赖于语言环境,因为 %date% 确实如此。在我的系统上,%date% 返回 dd/mm/yyyy;在其他人可能是 yymmdd
  • @eugeneK;而不是FOR %%F IN (E:\backups\7DbBackup_local\*.bak) DO IF...,你可以做FOR /f %%F IN ('xcopy E:\backups\7DbBackup_local\*.bak %tmp% /d:%date:~4,10% /l') DO。让您不再需要IF 来检查日期。
猜你喜欢
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2014-06-16
  • 1970-01-01
  • 2018-01-25
相关资源
最近更新 更多