【问题标题】:FORFILES date -after- (date calc in cmd file)FORFILES date -after- (在 cmd 文件中计算日期)
【发布时间】:2020-02-02 01:32:09
【问题描述】:

我想在 cmd 文件中使用 FORFILES,以便在给定日期到“今天”之后对所有文件执行操作。我可以使用 forfiles /d +07/10/2013 /c "cmd /c echo @fname" 之类的东西来处理 7/10/13 之后的所有事情,但我想要的是能够从“今天”之前的 90 天开始计算。

是否有可以在 cmd 文件中使用的日期计算语法,它可以让我指定“今天之前的 x 天”来输入 FORFILES?

我更喜欢不使用 VBS(并找到了一个可以在 VBS 中工作的代码 sn-p),虽然我也可以为 Powershell 重写我的脚本,但理想情况下我想坚持使用 cmd。

澄清一下,“-90”会查找所有超过 90 天的文件; "+90" 将查找所有比今天晚 90 天更新的文件(这基本上是无用的,因为文件很少写有未来的日期),而 "+7/30/2013" 将查找所有比 7/30 更新的文件/2013。我想要最后一个时间段,最好能够将一个天数变量传递给 CMD 文件,即“在今天之前的 x 天之后”,即“在最后 x 天”。因此,我希望能够在 cmd 文件中计算该日期,而不是使用上面显示的硬编码日期。

【问题讨论】:

  • 看我的回答here
  • 是一个批处理文件,创建/运行/删除一个VBS脚本,然后运行forfiles命令,好吗?
  • 出于几个原因,我想完全避免使用 VBS,但我意识到我正在切断一种方法。
  • Endoro,我认为这可行,但我不确定我是否理解它。似乎您正在构建一个目录列表文件,然后删除早于日期范围的条目。那是对的吗?这实际上可能很好,尤其是。在这种情况下,我实际上是在构建一个文件列表之后,我正在提供给其他东西。请澄清我是否没有正确解析,即“它是如何工作的”。 OBTW,我以为我在发布这个问题之前已经全面搜索了答案!

标签: windows date powershell batch-file cmd


【解决方案1】:

这里是针对forfiles关于/D +dddays的设计缺陷的变通方法,假设将来不能修改任何项目,并且基于两个嵌套的forfiles循环并依赖于事实forfiles 设置 ErrorLevel 以防没有项目符合提供的搜索条件:

rem Define minimum and maximum age in days here (0 means today):
set /A MINAGE=0, MAXAGE=90

set "MAXAGE=%MAXAGE:*-=%" & set "MINAGE=%MINAGE:*-=%" & set /A MAXINC=MAXAGE+1
> nul forfiles /D -%MINAGE% /C "cmd /C if @isdir==FALSE 2> nul forfiles /M @file /D -%MAXINC% || > con echo @fdate  @file"

外部forfiles 循环遍历至少与变量MINAGE 给出的一样旧的项目。内部forfiles 循环在从外部循环接收迭代文件@file 时最多迭代一次,如果它也至少与MAXINC 一样旧(等于MAXAGE 加上@987654333),则返回相同的文件@);如果不是,forfilesErrorLevel 设置为1,而|| 操作符又会执行以下命令,即echo,仅当ErrorLevel 已设置为一个非零值。

MINAGEMAXAGE 都不能是负数(命令 set "MAXAGE=%MAXAGE:*-=%"set "MINAGE=%MINAGE:*-=%" 删除减号以防万一)。引入了临时变量MAXINC,以便将MAXAGE 本身指定的年龄包含在返回的结果中。

重定向> nul 防止外部forfiles 返回空行,防止内部返回满足其搜索条件的项目(因为我们对那些不满足的项目感兴趣)。 2> nul 防止内部 forfiles 循环在违反其搜索条件时返回错误消息。 > con 覆盖 > nul 以使 echo 命令实际返回所需的项目。

if @isdir==FALSE 部分过滤掉目录,以便只处理文件。如果您只想处理目录,请将FALSE 更改为TRUE;如果您想同时处理两者,请将其完全删除。

【讨论】:

  • 伟大的工作,喜欢解释 :) 可能值得说明的是,使用 2nd/3rd set 命令可以防止负数。另外,什么是“redired items”?需要还是重定向?
  • 谢谢!我扩展了描述并按照建议修复了错字...
  • 这个答案值得更多的爱。很好的答案和解释。
【解决方案2】:

在 PowerShell 中,您可以执行以下操作:

$refdate = (Get-Date).AddDays(-90)
Get-ChildItem | Where-Object {
    $_.LastWriteTime -ge $refdate
} | Select-Object -Expand Name

【讨论】:

  • 我喜欢优雅的 powershell 答案,但我一直在将整个过程作为 cmd 文件、调用 powershell 脚本的 cmd 文件或 powershell 脚本之间来回折腾。在找到 FORFILES 之后,我认为它是理想的,直到我遇到这个日期问题,因为我实际上正在构建一个没有扩展名的文件列表,它将提供给其他一些命令。无论哪种方式,都感谢您提供漂亮的代码。
  • forfiles 可以提供一个可行的解决方案,如果不是因为您观察到的奇怪行为(我认为这是一个设计错误)。但是,CMD/batch 通常在处理日期方面很糟糕,所以我根本不会打扰。只需使用 PowerShell。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-19
  • 2021-12-04
  • 2019-09-28
  • 2021-06-02
  • 2010-09-26
相关资源
最近更新 更多