为什么 forfiles 命令会列出不是一天前的文件,尽管命令本身不是这样?

为什么 forfiles 命令会列出不是一天前的文件,尽管命令本身不是这样?

我正在执行的命令是forfiles -p"C:\testdata" -m*.* -d-1 -c"cmd /c echo @PATH\@FILE"

我已经指定只列出一天前的文件,但是当我执行该语句时,它会返回今天创建的文件列表。

这是为什么?我做错了什么吗?指定一个时间段而不是日期(例如 24 小时)会更好吗?

我拥有的 forfiles 版本如下。批处理文件正在 Windows XP 上运行。FORFILES v 1.1 - [email protected] - 4/98

答案1

Forfiles您使用的版本不是原生 XP 命令。它是该实用程序的旧版本,最初随其中一个一起分发W2K Resource Kits(我认为它甚至适用于 NT Resource Kit,尽管我不确定)。在 XP 上使用它本身并没有什么问题,但如果您仔细研究它的语法,它说(重点是我的):

-d[+|-][DDMMYY|DD] 选择日期 >= 或 <=DDMMYY 的文件(世界标准时间) 或文件日期 >= 或 <= (当前日期 - DD 天)

笔记世界标准时间在描述中。这意味着(1.1) forfiles使用与你想象的不同的时间戳 - 除非你的系统时间是 UTC(无偏移),没有夏令时。
举个例子可能更容易理解。我是 UTC+1,夏令时。
(今天的日期 - 2012-09-19)

  • 创建文件并执行目录:

2012-09-19 00:14 5 zzz_utc.txt

它有今天的日期,所以它不应该被 forfiles 选择,让我们检查一下:

FORFILES -pc:\temp -mzzz_utc.* -d-1 -c"CMD /C Echo @FILE"
zzz_utc.txt

但它确实被选中了!为什么?让我们看看文件 UTC 时间(以下命令从 powershell 运行):

ls .\zzz_utc.txt |select LastAccessTime,LastAccessTimeUTC

LastAccessTime                          LastAccessTimeUtc
--------------                          -----------------
2012-09-19 00:15:11                     2012-09-18 22:15:11

如你看到的,时间Utc- 使用的(1.1) forfiles是昨天的!这就是它被工具选中的原因。

答案2

“...我希望只列出一天前的文件...”

您指的是“昨天创建的文件”吗?即(今天是 9 月 18 日),修改日期/时间≥ 9 月 17 日 0000(凌晨午夜)和≤ 9 月 17 日 2359.60(午夜结束)的文件。好吧,这是两个日期/时间限制,并且forfiles不允许您指定多个。底线:我相信这forfiles不会做到这一点。

... 但是,当我尝试/d -1使用 Windows 7 时,我得到的是昨天或之前创建的文件。所以可能是 Windows XP 版本forfiles有问题。

答案3

来自精细文档(重点是我的):

选择最后修改日期晚于或等于 (+) 当前日期加上指定天数,或早于或等于 (-) 当前日期的文件减去指定的天数

编辑:

也许您可以尝试使用 VBScript:

Set args = WScript.Arguments.Named
Set fso  = CreateObject("Scripting.FileSystemObject")

d = 0
p = "."

If args.Exists("?") Or args.Count = 0 Then
  WScript.Echo "Usage: cscript " & WScript.ScriptName & " [/d:DAYS] [/p:PATH]"
  WScript.Quit(0)
End If

If args.Exists("d") Then d = args("d")
If args.Exists("p") Then p = args("p")

refDate = DateAdd("d", d, Now)
TraverseFolders fso.GetFolder(p)

Sub TraverseFolders(fldr)
  For Each f In fldr.Subfolders
    TraverseFolders(f)
  Next
  For Each f In fldr.Files
    If f.DateLastModified < refDate Then
      WScript.StdOut.WriteLine f.Path
      'f.Delete
    End If
  Next
End Sub

答案4

似乎 FORFILES /D -1 即使在 Windows 8 和 Windows Server 2008 R2 上也有一个错误(无法使其工作 - 选择所有文件 - 在具有希腊日期的系统上)

您可以按照上面一些评论中的建议解析 %date%,但请注意,例如在 Windows 8 上,日期首先显示 3 个字母,包括星期名称和空格字符,然后是经典日期格式。此外,该日期将采用本地化格式,而根据 forfiles /?,FORFILES /D 需要 dd/MM/yyyy 格式的日期(至少在 Win8 上)。

更正:似乎对 /D -dd 的作用存在误解(我和其他人通过网上搜索判断),似乎它不会搜索 dd 天前的文件,而是搜索早于 dd 天的文件

因此您需要使用 FORFILES 的 /D +dd/MM/yyyy 语法并传入昨天的日期以查找日期晚于昨天的所有文件。要自动执行此操作,您可以使用 %date% 并使用 %date:~7,2%/%date:~4,2%/%date:~-4% 或类似方法进行解析(可能需要根据您的语言环境重新排序那里的日期部分)

相关内容