【问题标题】:Batch file: Iterate over files modified since a given date批处理文件:迭代自给定日期以来修改的文件
【发布时间】:2010-08-13 18:24:05
【问题描述】:

我想创建一个批处理文件,在每个匹配自某个日期以来修改的通配符(例如 *.jpg)的文件上执行命令(删除文件,举个简单的例子,尽管我的命令是自定义/不同的) (例如 2010 年 1 月 1 日或之后)。日期可以硬编码在批处理文件中,也可以作为命令行参数传递。

伪代码:

foreach file C:\Images\*.jpg modified-since 1-1-2010 do
del file

我更喜欢纯批处理文件,而不是 PowerShell、VBScript 等。如果无法使用纯批处理语言,我可以使用小型/免费的第三方命令行程序来帮助生成修改后的文件文件列表。我需要支持在 Windows 2000 或更高版本中运行。


我使用的最终解决方案:

(根据 pipitas 的回答稍作修改)

@ECHO OFF
for /f "usebackq tokens=1-7* delims=/: " %%I in (`dir/o-d/tw ^| findstr /I .jpg`) do (
  if "%%K%%I%%J %%N %%L%%M" GEQ "20100801 AM 0000" (
    del /P %%P
  )
)

一些注意事项:删除 /P 以在每次删除时不需要确认是/否。我转义了 % 字符,以便它们可以在 .bat 文件中工作。 ^ 是逃避管道所必需的。 “usebackq”使反引号分隔要执行的命令(而不是搜索文字字符串或文件),tokens 设置变量的数量以将已解析的行放在以 %I 开头,并且 delims 设置分隔符(包括尾随空格) 用于将行解析为这些标记。

我添加了 .jpg 作为 findstr 搜索字符串,因为我只想处理 .jpg 文件。一些可能的问题是您的语言环境可能会以不同的方式打印日期,需要不同数量的变量或不同的分隔符,并且您可能会有一些误报匹配文件名中嵌入的“.jpg”(需要 findstr 正则表达式等) .

如果您不需要支持 Windows 2000 及更早版本,按照 Johannes 的建议使用 forfiles 会更容易。

【问题讨论】:

  • 批处理文件将在 Windows 下执行,但它需要在每台 Windows 2000 或更高版本的机器上运行,因此它不能使用更新的 Windows 版本中的任何内容。我可以使用任何内置于 Windows 2000 或更高版本的东西,但正如我所说,我建议不要使用 VBScript 等,除非直接的批处理文件无法做到这一点。
  • 遗憾的是,Windows 2000 的要求排除了 Forfiles,这正是您想要的。

标签: datetime file batch-file loops last-modified


【解决方案1】:

首先是一些初步的:

  • dir /od /tw /s ..\path\to\somedir: 列出所有目录的文件+子目录,按日期+最后修改时间排序,
  • dir /o-d /tw /s ..\path\to\somedir: 相同,但顺序相反(最旧的在后)。

接下来,我对现有路径使用本地示例。走吧:

dir /tc /o-d /s gstmp\*yell*.tif ^| findstr 2010
 Volume in Laufwerk C: hat keine Bezeichnung.
 Volumeseriennummer: D479-1658

 Verzeichnis von C:\downloads\gstmp

08/06/2010  05:01 PM           19 compression-g4-emptypage-tiffsep1(Yellow).tif
08/06/2010  05:00 PM           19 compression-lzw-emptypage-tiffsep1(Yellow).tif
08/06/2010  04:57 PM           19 compression-g3-tiffsep1(Yellow).tif
08/06/2010  04:57 PM           19 compression-crle-tiffsep1(Yellow).tif
08/06/2010  04:56 PM           19 compression-pack-share-tiffsep1(Yellow).tif
08/06/2010  04:53 PM           19 compression-g4-share-tiffsep1(Yellow).tif
08/06/2010  04:52 PM           19 compression-lzw-share-tiffsep1(Yellow).tif
08/06/2010  04:51 PM           19 compression-default-share-tiffsep1(Yellow).tif
08/06/2010  03:59 PM           19 compression-none-share-tiffsep.Yellow.tif
08/06/2010  03:55 PM           19 share-tiffsep.Yellow.tif
              10 Datei(en)       190 Bytes

目前我们不喜欢额外的标题和摘要信息。我们可以通过过滤某些东西来摆脱这种情况。我将简单地使用“2010”。

但现在真正的问题开始了:创建日期和时间可能会以不同的格式打印,具体取决于您的“语言环境”。你可以看到你自己,它目前对我的看法。

如果我们可以将日期显示为与数字顺序完全匹配的格式,它不会起作用吗?然后我们可以实现一些逻辑,通过简单的数字比较来决定删除。让我们试试(如果这对我有用,它不一定对你有用——你可能需要适应你的语言环境)。请注意我正在使用的“反引号”(“``”)以及 ^ 符号:

for /f "usebackq tokens=1-7* delims=/: " %I in (`dir/tc/o-d/s gstmp\*yell*.tif ^
   ^| findstr 2010`) do echo.    %I %J %K %L %M %N %O %P

在这里输出:

08 06 2010 05 01 PM 19 compression-g4-emptypage-tiffsep1(Yellow).tif
08 06 2010 05 00 PM 19 compression-lzw-emptypage-tiffsep1(Yellow).tif
08 06 2010 04 57 PM 19 compression-g3-tiffsep1(Yellow).tif
08 06 2010 04 57 PM 19 compression-crle-tiffsep1(Yellow).tif
08 06 2010 04 56 PM 19 compression-pack-share-tiffsep1(Yellow).tif
08 06 2010 04 53 PM 19 compression-g4-share-tiffsep1(Yellow).tif
08 06 2010 04 52 PM 19 compression-lzw-share-tiffsep1(Yellow).tif
08 06 2010 04 51 PM 19 compression-default-share-tiffsep1(Yellow).tif
08 06 2010 03 59 PM 19 compression-none-share-tiffsep.Yellow.tif
08 06 2010 03 55 PM 19 share-tiffsep.Yellow.tif

我们快到了,但还没有完全做到。我们需要将令牌的顺序 %I %J %K 更改为 %K %I %J,以便我们的日期显示为 2010 08 06 而不是 08 06 2010。此外,如果我们写出正确的不带空格的标记,那么可以得到一个日期+时间字符串,这样就可以很容易地进行比较。另外,我们跳过%O 并用箭头替换它,只是为了好玩:

for /f "usebackq tokens=1-7* delims=/: " %I in (`dir/tc/o-d/s gstmp\*yell*.tif ^
   ^| findstr 2010`) do echo.    %K%I%J%L%M%N ==^> %P

现在输出更改为:

201008060501PM ==> compression-g4-emptypage-tiffsep1(Yellow).tif
201008060500PM ==> compression-lzw-emptypage-tiffsep1(Yellow).tif
201008060457PM ==> compression-g3-tiffsep1(Yellow).tif
201008060457PM ==> compression-crle-tiffsep1(Yellow).tif
201008060456PM ==> compression-pack-share-tiffsep1(Yellow).tif
201008060453PM ==> compression-g4-share-tiffsep1(Yellow).tif
201008060452PM ==> compression-lzw-share-tiffsep1(Yellow).tif
201008060451PM ==> compression-default-share-tiffsep1(Yellow).tif
201008060359PM ==> compression-none-share-tiffsep.Yellow.tif
201008060355PM ==> share-tiffsep.Yellow.tif

现在您几乎可以比较第一个字段了。

但是考虑一下:我的时间以 12 小时为周期,AMPM。因此,为了进行数字比较,我们必须将 PM 和 AM 分别替换为一个数值,这样我们对 04:51 AM04:50 PM 的翻译仍然会以正确的方式按数字排序。

现在怎么样:

for /f "usebackq tokens=1-7* delims=/: " %I in (`dir/tc/o-d/s gstmp\*yell*.tif ^
     ^| findstr 2010`) do  (
        if "%K%I%J %N %L%M" GEQ "20100806 PM 0457"  (
            echo.   [ %K-%I-%J %L:%M %N    %P. ]
        )
 )

这列出了所有应该删除的文件,还显示了它们各自的日期。要真的删除,我们只需将最后的echo. ... %P. 替换为del/p/f/s %P

【讨论】:

  • 谢谢!有时,我认为批处理文件是微软对我们必须做的非常糟糕的事情的报复。我做了一些编辑并让它工作。不过,在 .bat 文件中做任何不重要的事情的痛苦确实让我重新考虑不使用 VBScript。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多