使用Windows批处理列出比另一个文件更新的文件

时间:2018-09-06 20:24:20

标签: cmd

dir /b 

列出目录中文件的名称。您如何只列出比指定文件新的文件,例如foo.txt?

2 个答案:

答案 0 :(得分:1)

此批处理文件可用于此任务:

@echo off
if "%~1" == "" goto :EOF
if not exist "%~1" goto :EOF
if exist "%~1\" goto :EOF

echo Files newer than %~nx1 in directory: %~dp1
echo/

for /F "eol=| delims=" %%I in ('dir "%~dp1" /A-D /B /O-D') do (
    if /I "%~nx1" == "%%I" goto ExitLoop
    echo %%I
)

:ExitLoop
echo/
pause

批处理文件的执行在名为的批处理文件上退出

  • 不带参数
  • 带有不是现有文件/目录或
  • 的参数字符串
  • 带有参数字符串,该参数字符串是现有目录而不是文件。

命令 FOR 在以cmd.exe /C为背景的单独命令过程中执行命令 DIR

DIR 逐行输出

  • 仅由于/A-D而出现文件(属性而非目录)
  • 仅出于/B的原因以裸格式显示文件名+文件扩展名
  • 按上次修改/写入日期的先后顺序排列,这意味着由于/O-D,最新的文件排在最前面,而最早的文件排在最后
  • 所有文件,包括指定文件目录中的隐藏文件。

FOR 捕获为处理已启动的后台命令过程的 STDOUT 而编写的所有内容,然后逐行处理捕获的行,并跳过此处不存在的空行。

FOR 默认情况下忽略以分号开头的行。文件名可以以;开头。因此,使用选项eol=|将行尾字符从默认;重新定义为竖线|,因为该字符不能在文件名中使用。

FOR 默认情况下使用空格和制表符作为分隔符将每一行分成子字符串,并仅将第一个用空格/制表符分隔的字符串分配给指定的循环变量I。因此,使用选项delims=将分隔符列表重新定义为一个空的分隔符列表,从而导致行拆分无法处理包含一个或多个空格的正确文件名。

DIR 输出按日期从最新到最早的文件名。因此,在 FOR 循环中,使用不区分大小写的字符串比较来检查当前文件名是否等于指定的文件名。如果此条件成立,则退出循环并跳转到循环下方的标签。否则,当前文件名将输出到控制台。

最后,在通过双击批处理文件启动了批处理文件的情况下,批处理文件将暂停执行该批处理文件,以便能够读取列表。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /? ...说明了批处理文件参数引用。
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • pause /?

注意:如果一个或多个文件的最后修改日期与指定文件的修改日期完全相同,则无法预测该代码还将输出其中的哪个文件。需要另外一个 IF 条件来排除文件日期与指定文件相同的文件。以下 IF 条件可用于退出在 FOR正文中现有 IF 条件后之后具有相同日期/时间的文件上的循环循环。

for %%J in ("%~dp1%%I") do if "%%~tJ" == "%~t1" goto ExitLoop

但是,此 IF 条件仅比较文件日期/时间,没有秒。因此,如果当前文件具有相同的日期,小时和分钟,但是第二个值更高,则退出循环也将导致循环,因此考虑到第二个Windows命令处理器不使用此代码时,第二个值实际上比指定文件新。

答案 1 :(得分:0)

如果您愿意使用PowerShell,这非常简单。在.ps1脚本中使用时,它不那么麻烦,但是可以在.bat文件脚本中完成。

SET "SEARCHDIR=C:\src\t"
SET "REFFILE=C:\src\t\truename.bat"

powershell -NoProfile -Command ^
    "Get-ChildItem -File -Path "%SEARCHDIR%" |" ^
        "Where-Object -FilterScript { $_.LastWriteTime -ge (Get-ChildItem -Path %REFFILE%).LastWriteTime }"

如果您知道要用作起点的日期,则可以将其放入命令中。

powershell -NoProfile -Command ^
    "Get-ChildItem -File -Path "%SEARCHDIR%" |" ^
        "Where-Object -FilterScript { $_.LastWriteTime -ge '2018-08-14' }"