首页 > 解决方案 > 如何从两个文件夹中搜索特定文件并比较时间戳(如果相同或使用批处理 Windows 脚本给出的最新文件是什么)

问题描述

我有用于在所有文件中搜索和比较的初始代码:

SET FILE1=Directory1\* 
SET FILE2=Directory2\* 


FOR %%i IN (%FILE1%) DO SET DATE1=%%~ti
FOR %%i IN (%FILE2%) DO SET DATE2=%%~ti
IF "%DATE1%"=="%DATE2%" ECHO Files have same age && GOTO END

FOR /F %%i IN ('DIR /B /O:D %FILE1% %FILE2%') DO SET NEWEST=%%i
ECHO Newer file is %NEWEST%

:END

如何根据该特定文件名应该搜索和比较的目录进行具体搜索?

示例:我想在其名称中搜索所有特定的 INV 和 SLS 文件,并比较是否相同或最新文件是什么:

在目录 1 中:

Flatfile           Timestamp
-------           ----------
INVF032            3/14/2019
INVF021            3/14/2019
KVNF234            3/14/2019
SLS0234            3/14/2019
SLS3211            3/14/2019

在目录 2 中:

Flatfile           Timestamp
-------           ----------
INVF032            3/19/2019
INVF021            3/19/2019
KVNF234            3/19/2019
SLS0234            3/19/2019
SLS3211            3/19/2019

输出:

Newer files is:
INVF032            3/19/2019
INVF021            3/19/2019
SLS0234            3/19/2019
SLS3211            3/19/2019

在 Windows Server 2008 中运行后在输出中添加一些错误回显(它说实例不可用):

C:\Users\ksaycon\Desktop>sample.bat

C:\Users\ksaycon\Desktop>rem // Author: KJSaycon: Batch Script Code for JDE Flat
file Extraction version 1

C:\Users\ksaycon\Desktop>setlocal EnableExtensions DisableDelayedExpansion

C:\Users\ksaycon\Desktop>echo "Program is running. ."
"Program is running. ."

C:\Users\ksaycon\Desktop>rem // Defining the constant variables and pointers:

C:\Users\ksaycon\Desktop>set "_ROOT=C:\Users\ksaycon\Desktop\."   & rem // (set
root directory; `C:\Users\ksaycon\Desktop\.` means is script's parent directory,
 `.` means current PATH)

C:\Users\ksaycon\Desktop>set "_DIR1=C:\Users\ksaycon\Desktop\.\fp_files1\"   & r
em // (1st directory containing files)

C:\Users\ksaycon\Desktop>set "_DIR2=C:\Users\ksaycon\Desktop\.\fp_files2\"   & r
em // (2nd directory containing files)

C:\Users\ksaycon\Desktop>set _MASKS="*INV*" "*SLS*" "*PUR*"      & rem // (list
of quoted file masks, find string like *char*)

C:\Users\ksaycon\Desktop>set "_TMP1=C:\Users\ksaycon\AppData\Local\Temp\179\samp
le_1_27853.tmp"   & rem // (set temp file 1)

C:\Users\ksaycon\Desktop>set "_TMP2=C:\Users\ksaycon\AppData\Local\Temp\179\samp
le_2_15411.tmp"   & rem // (set temp file 2)

C:\Users\ksaycon\Desktop>rem // Loop 1st directory to be an absolute path:

C:\Users\ksaycon\Desktop>for %E in ("C:\Users\ksaycon\Desktop\.\fp_files1\") do
set "RDIR1=%~fE"

C:\Users\ksaycon\Desktop>set "RDIR1=C:\Users\ksaycon\Desktop\fp_files1\"

C:\Users\ksaycon\Desktop>rem // Loop 2nd directory to be an absolute path:

C:\Users\ksaycon\Desktop>for %E in ("C:\Users\ksaycon\Desktop\.\fp_files2\") do
set "RDIR2=%~fE"

C:\Users\ksaycon\Desktop>set "RDIR2=C:\Users\ksaycon\Desktop\fp_files2\"

C:\Users\ksaycon\Desktop>rem // Write all matching files in 1st directory to 1st
 temporary file using assembly language function PUSHD:

C:\Users\ksaycon\Desktop>pushd "C:\Users\ksaycon\Desktop\fp_files1\"   && (
for %F in ("*INV*" "*SLS*" "*PUR*") do (echo(%~nxF )
 popd
) 1>"C:\Users\ksaycon\AppData\Local\Temp\179\sample_1_27853.tmp"

C:\Users\ksaycon\Desktop>rem // Write all matching files in 2nd directory to 2nd
 temporary file using assembly language function PUSHD:

C:\Users\ksaycon\Desktop>pushd "C:\Users\ksaycon\Desktop\fp_files2\"   && (
for %F in ("*INV*" "*SLS*" "*PUR*") do (echo(%~nxF )
 popd
) 1>"C:\Users\ksaycon\AppData\Local\Temp\179\sample_2_15411.tmp"

C:\Users\ksaycon\Desktop>rem // Loop over all common files from both temporary f
iles:

C:\Users\ksaycon\Desktop>for /F %L in ('findstr /L /I /X /G:"C:\Users\ksaycon\Ap
pData\Local\Temp\179\sample_1_27853.tmp" "C:\Users\ksaycon\AppData\Local\Temp\17
9\sample_2_15411.tmp"') do (
rem // Build absolute `wmic`-compatible file paths:
 set "FILE1=C:\\Users\\ksaycon\\Desktop\\fp_files1\\\\%L"   & set "FILE2=C:\\Use
rs\\ksaycon\\Desktop\\fp_files2\\\\%L"
 setlocal EnableDelayedExpansion
 rem set "FILE1=&=&!" & set "FILE2=&=&!"
 rem // Loop to get standardised file date/time (last modification) of 1st file
by `wmic`:
 for /F "skip=1" %K in ('wmic DataFile where "Name='!FILE1!'" get LastModified')
 do for /F %K in ("%K") do set "DATE1=%K"
 rem // Loop to get standardised file date/time (last modification) of 2nd file
by `wmic`:
 for /F "skip=1" %K in ('wmic DataFile where "Name='!FILE2!'" get LastModified')
 do for /F %K in ("%K") do set "DATE2=%K"
 rem // If Compare file dates/times (last mod.) of both files and return differi
ng ones:
 if !DATE1! LSS !DATE2! echo "!FILE1:\\=\!" is older than "!FILE2:\\=\!"
 if !DATE1! GTR !DATE2! echo "!FILE1:\\=\!" is newer than "!FILE2:\\=\!"
 if !DATE1! EQU !DATE2! echo "!FILE1:\\=\!" and "!FILE2:\\=\!" are of same age

 endlocal
)

C:\Users\ksaycon\Desktop>(
rem // Build absolute `wmic`-compatible file paths:
 set "FILE1=C:\\Users\\ksaycon\\Desktop\\fp_files1\\\\FFPDFINV01"   & set "FILE2
=C:\\Users\\ksaycon\\Desktop\\fp_files2\\\\FFPDFINV01"
 setlocal EnableDelayedExpansion
 rem set "FILE1=&=&!" & set "FILE2=&=&!"
 rem // Loop to get standardised file date/time (last modification) of 1st file
by `wmic`:
 for /F "skip=1" %K in ('wmic DataFile where "Name='!FILE1!'" get LastModified')
 do for /F %K in ("%K") do set "DATE1=%K"
 rem // Loop to get standardised file date/time (last modification) of 2nd file
by `wmic`:
 for /F "skip=1" %K in ('wmic DataFile where "Name='!FILE2!'" get LastModified')
 do for /F %K in ("%K") do set "DATE2=%K"
 rem // If Compare file dates/times (last mod.) of both files and return differi
ng ones:
 if !DATE1! LSS !DATE2! echo "!FILE1:\\=\!" is older than "!FILE2:\\=\!"
 if !DATE1! GTR !DATE2! echo "!FILE1:\\=\!" is newer than "!FILE2:\\=\!"
 if !DATE1! EQU !DATE2! echo "!FILE1:\\=\!" and "!FILE2:\\=\!" are of same age

 endlocal
)
No Instance(s) Available.

"  do set "DATE1=Desktop>for /F %K in ("
No Instance(s) Available.

"  do set "DATE2=Desktop>for /F %K in ("
"C:\Users\ksaycon\Desktop\fp_files1\\FFPDFINV01" and "C:\Users\ksaycon\Desktop\f
p_files2\\FFPDFINV01" are of same age

C:\Users\ksaycon\Desktop>rem // Clean up temporary files:

C:\Users\ksaycon\Desktop>del "C:\Users\ksaycon\AppData\Local\Temp\179\sample_1_2
7853.tmp" "C:\Users\ksaycon\AppData\Local\Temp\179\sample_2_15411.tmp"

C:\Users\ksaycon\Desktop>echo "Clearing up garbage collection! Done."
"Clearing up garbage collection! Done."

C:\Users\ksaycon\Desktop>endlocal

C:\Users\ksaycon\Desktop>exit /B

C:\Users\ksaycon\Desktop>

标签: windowsfilebatch-filescripting

解决方案


您的意图不是很清楚,特别是因为您想要的输出不明确,因为它不包含文件的父目录。

无论如何,这是一个执行您想要的脚本(至少在我的理解中),因为只有两个目录中都存在的文件才会被处理。

所以这是代码,包含几个解释性rem-remarks:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ROOT=%~dp0." & rem // (common root directory; `%~dp0.` is script's parent, `.` is current)
set "_DIR1=%_ROOT%\Directory1" & rem // (1st directory containing files)
set "_DIR2=%_ROOT%\Directory2" & rem // (2nd directory containing files)
set _MASKS="INV*." "SLS*."     & rem // (list of quoted file masks)
set "_TMP1=%TEMP%\%~n0_1_%RANDOM%.tmp" & rem // (1st temporary file)
set "_TMP2=%TEMP%\%~n0_2_%RANDOM%.tmp" & rem // (2nd temporary file)

rem // Resolve 1st directory to be an absolute path:
for %%E in ("%_DIR1%") do set "RDIR1=%%~fE"
rem // Resolve 2nd directory to be an absolute path:
for %%E in ("%_DIR2%") do set "RDIR2=%%~fE"

rem // Write all matching files in 1st directory to 1st temporary file:
pushd "%RDIR1%" && (
    for %%F in (%_MASKS%) do (
        echo(%%~nxF
    )
    popd
) > "%_TMP1%"
rem // Write all matching files in 2nd directory to 2nd temporary file:
pushd "%RDIR2%" && (
    for %%F in (%_MASKS%) do (
        echo(%%~nxF
    )
    popd
) > "%_TMP2%"

rem // Loop over all common files from both temporary files:
for /F %%L in ('findstr /L /I /X /G:"%_TMP1%" "%_TMP2%"') do (
    rem // Build absolute `wmic`-compatible file paths:
    set "FILE1=%RDIR1:\=\\%\\%%L" & set "FILE2=%RDIR2:\=\\%\\%%L"
    setlocal EnableDelayedExpansion
    rem set "FILE1=%!FILE1:&=&!" & set "FILE2=%!FILE2:&=&!"
    rem // Get standardised file date/time (last modification) of 1st file by `wmic`:
    for /F "skip=1" %%K in ('wmic DataFile where "Name='!FILE1!'" get LastModified') do for /F %%K in ("%%K") do set "DATE1=%%K"
    rem // Get standardised file date/time (last modification) of 2nd file by `wmic`:
    for /F "skip=1" %%K in ('wmic DataFile where "Name='!FILE2!'" get LastModified') do for /F %%K in ("%%K") do set "DATE2=%%K"
    rem // Compare file dates/times (last mod.) of both files and return differing ones:
    if !DATE1! leq !DATE2! echo "!FILE1:\\=\!" is older than "!FILE2:\\=\!"
    if !DATE1! gtr !DATE2! echo "!FILE1:\\=\!" is newer than "!FILE2:\\=\!"
    if !DATE1! equ !DATE2! echo "!FILE1:\\=\!" and "!FILE2:\\=\!" are of same age
    endlocal
)

rem // Clean up temporary files:
del "%_TMP1%" "%_TMP2%"

endlocal
exit /B

核心命令是:

  • findstr, 返回两个给定目录中共有的所有文件;
  • wmic, 以标准化方式(格式如YYYYMMDDhhmmss.uuuuuu+ZZZ)检索文件的最后修改日期/时间,可以很容易地将其作为字符串进行比较;

推荐阅读