batch - 对具有特定创建日期的每个文件执行命令

时间:2016-09-29 11:34:43

标签: windows batch-file cmd

得到了这段代码:

forfiles /P %ParentFolder% /S /M %Format% /C "cmd /c %exeFile% @path"

为每个匹配格式的文件执行一些exe作为参数。

任何方式添加"创建日期"作为通过CMD运行命令的条件?

类似的东西:

目录中的所有文件(递归)X如果创建日期比较新,那么1天前使用此文件的路径作为参数执行(运行)某些exe

2 个答案:

答案 0 :(得分:1)

forfiles无法做到这一点,因为在提供/D选项时,它仅仅考虑最后修改日期(甚至不是修改时间)。

不幸的是,没有日期/时间数学的本机命令,所以我建议切换到能够做到这一点的语言;例如,PowerShell,VBScript,JavaScript(这些都是Windows XP以前的原生版本)。

如果可以使用修改日期,并且使用今天的日期进行简单检查就足够了,可以使用以下forfiles命令行:

forfiles /S /P "%ParentFolder%" /M "%Format%" /D +0 /C "cmd /C \"%exeFile%\" @path"

带有非负数的/D选项允许forfiles返回在今天或之后的给定天数内修改过的文件(尽管您需要时间机器;因此我认为这是一个设计缺陷)。对于给定天数的+0,将返回今天修改的所有匹配文件,因为forfiles /D仅检查修改日期,但不关心修改时间。

如果对创建日期与今天的日期进行简单的相等检查对您来说很合适,那么可以很容易地在脚本中完成(请参阅所有解释性rem说明如何以下脚本工作):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "ParentFolder=."
set "Format=*.*"
set "exeFile=" & rem // (full path to executable file)
set "tmpFile=%TEMP%\%~n0_%RANDOM%.tmp"

rem // Create a temporary file and retrieve its creation date:
2> nul del "%tmpFile%" & > "%tmpFile%" break & set "TODAY="
for /F "skip=5" %%J in ('dir /N /4 /-C /T:C "%tmpFile%"') do (
    if not defined TODAY set "TODAY=%%J" & del "%tmpFile%"
)

rem // Change to predefined parent directory:
pushd "%ParentFolder%" && (
    rem // Return all files recursively:
    for /F "delims=" %%I in ('dir /B /S /A:-D "%Format%"') do (
        rem // Determine the creation date for the current file:
        set "FIRST=#"
        for /F "skip=5" %%J in ('dir /N /-C /T:C "%%I"') do (
            rem // Regard line listing file only, ignore summary lines:
            if defined FIRST (
                set "FIRST="
                rem // Check creation date against today:
                if "%%J"=="%TODAY%" (
                    rem // Return files created today:
                    echo "%%I" has been created today.
                    rem // Run external program on found file:
                    if defined exeFile "%exeFile%" "%%I"
                )
            )
        )
    )
    rem // Restore previous working directory:
    popd
)

endlocal
exit /B

我在这里使用两个dir命令行:

  1. 第一个返回一个简单的文件列表(/S;由于/A:-D没有目录),没有任何日期/时间,页眉和页脚,由于切换/B;不使用此开关会导致整个输出和每个迭代子目录的页眉和页脚行,因此输出将非常复杂,无法解析;
  2. 第二个接收第一个返回的文件;由于没有/B/N选项,因此返回文件创建日期/时间(/T:C);对于每个文件,输出如下所示:

     Volume in drive D is DATA
     Volume Serial Number is 0000-0000
    
     Directory of D:\Data
    
    2016/09/29  16:00               1024 current_file.txt
                   1 File(s)           1024 bytes
                   0 Dir(s)   1099511623680 bytes free
    

    构成创建日期的第六行的第一个标记被拆分并与当前日期%DATE%进行比较;要忽略标头,使用skip=5循环的for /F选项;要忽略摘要行,使用变量FIRST;

  3. 请注意,日期格式取决于区域设置;只要日期中没有空格,这就没有问题,因为当前日期也是由临时文件上应用的dir命令决定的。

答案 1 :(得分:0)

查看forfiles /?会显示切换/D,该文件将排除比{{1}的给定值更年轻(/d -<days>)或更旧(/d +<days>)的文件}}

如您所希望的那样,您可以将<days>设置为0。

请注意,这将在更改日期

上查看

其他方式是使用<date> - 循环并使用for /r获取创建日期的列表;要对其进行排序,请添加dir /T:C。然后使用/O-D循环分隔它以获取for /f的输出行和另一个分隔它(在没有嵌套循环的情况下可能更容易)。

您可以将创建日期与dir进行比较,或者在使用一天= 24小时时将创建时间与%date%进行比较。