1.比较两个目录的差异,支持目录的递归比较,判断标准是文件内容是否相同。
2.生成标准化的结果报告
小技巧:
1.如果加入-d参数,则会把所有的比较结果按照目录为单位输出到一个文件中。
2.对于*-diff.txt文件,可以用查找替换,把它变成一个bat文件,可以对有差异的文件用更高级的比较器进行比较。我经常会把diff.txt中的diff替换成call bc /w ,把 . 替换成rem,然后另存为bat格式。如果大家有要求,我考虑把它变成一个标准的输出格式
目前尚未实现的功能:
1. 除了文本之外的其他输出格式支持,比如xml或html的输出格式
下载代码如下:
1
@echo off2
rem ============================================================================3
rem 本程序负责比较两个目录中的所有文件是否一致,并且按照一定的顺序把比较结果输出4
rem 到文件中。程序的行为包括如下几个方面:5
rem 1)遍历:仅仅当前目录还是需要遍历整个目录,用/s参数控制,附加的精细控制参数6
rem 还包括/f和/x参数7
rem 2)比较:单向比较还是双向比较,用/d参数控制。双向比较可以得到src-dir中缺失的8
rem 所有文件列表,单向比较仅可以得到部分缺失的文件列表。9
rem 2)显示:结果的显示包括原始格式输出、经过分类的输出。分类的输出有可以分输出10
rem 到不同文件和同一文件。原始格式输出到*-all文件中,相同文件输出到*-same文件,11
rem 不同文件输出到*-diff中,多余文件输出到*-redu,缺失文件输出到*-lost中。参数12
rem /d控制把*-redu,*-lost,*-same,*-diff合并成一个输出*-dir文件。参数/q关闭控制13
rem 台内容显示。14
rem ============================================================================15

16
rem 关闭cmd的扩展开关,保证生成临时bat的时候不出异常17
set TSTEXT=a18
if "!TSTEXT!"=="a" cmd.exe /V:OFF /C %0 %* & exit /b19
set TSTEXT=20

21
rem 保存当前工作目录22
set PWD=%CD%23
rem 如果第一个参数是DEBUG,表明打开调试选项24
rem 需要设DEBUG变量,剩余命令行放在CMDLINE变量中25
set DEBUG=26
set CMDLINE0=%*27
if #%1# == #DEBUG# set DEBUG=on28
if #%1# == #debug# set DEBUG=on29
if #%DEBUG%# == #on# set CMDLINE=%CMDLINE0:~5%30
if NOT #%DEBUG%# == #on# set CMDLINE=%CMDLINE0%31
set CMDLINE0=32
if #%DEBUG%# == #on# shift33
@if #%DEBUG%# == #on# @echo on34

35
rem 是否显示帮助36
if "%1" == "" goto help37
if "%1" == "/?" goto help38
if "%1" == "-?" goto help39
if "%1" == "?" goto help40
for %%a in (help HELP /help /HELP -help -HELP --help --HELP h H /h /H -h -H --h --H ) do if "%1" == "%%a" goto help41

42
rem 开始参数识别和检测43
set DIR1=44
set DIR2=45

46
set O_SUB=47
set O_PAT=*.*48
set O_EXC=49
set O_DIR=50
set O_QUITE=51
set O_SUP=52
set O_PRE=fc-o53
set O_OVER=54
set O_POST=txt55
set O_CMDL=/n+/w56
set O_MODI=57
set O_VIEW=58
if "%EDITOR%"=="" (set P_EDTR=notepad.exe) else (set P_EDTR=%EDITOR%)59

60
:opt_an61
for %%a in ( /s -s /S -S ) do if "%1" == "%%a" set O_SUB=y&& goto opt_nx62
for %%a in ( /f -f /F -F ) do if "%1" == "%%a" goto opt_pat63
for %%a in ( /x -x /X -X ) do if "%1" == "%%a" goto opt_exc64
for %%a in ( /d -d /D -D ) do if "%1" == "%%a" set O_DIR=y&& goto opt_nx65
for %%a in ( /q -q /Q -Q ) do if "%1" == "%%a" set O_QUITE=y&& goto opt_nx66
for %%a in ( /u -u /U -U ) do if "%1" == "%%a" set O_SUP=y&& goto opt_nx67
for %%a in ( /p -p /P -P ) do if "%1" == "%%a" goto opt_pre68
for %%a in ( /o -o /O -O ) do if "%1" == "%%a" set O_OVER=y&& goto opt_nx69
for %%a in ( /t -t /T -T ) do if "%1" == "%%a" set O_POST=htm&& goto opt_nx70
for %%a in ( /c -c /C -C ) do if "%1" == "%%a" goto opt_cmd71
for %%a in ( /m -m /M -M ) do if "%1" == "%%a" set O_MODI=y&& goto opt_nx72
for %%a in ( /v -v /V -V ) do if "%1" == "%%a" set O_VIEW=y&& goto opt_nx73
if "%DIR1%" == "" (for /d %%v in (%1) do set DIR1=%%~fv&&set DIR1S=%%~fsv) else (for /d %%v in (%1) do set DIR2=%%~fv&&set DIR2S=%%~fsv)74
goto opt_nx75
:opt_pat76
shift 77
set O_PAT=%178
goto opt_nx79
:opt_exc80
shift 81
set O_EXC=%182
goto opt_nx83
:opt_cmd84
shift 85
set O_CMDL=%186
goto opt_nx87
:opt_pre88
shift89
set O_PRE=%190
:opt_nx91
shift92
if not "%1" == "" goto opt_an93

94
if "%DIR1%" == "" goto help95
if "%DIR2%" == "" goto help96
goto start97

98
:help99
echo -----======================================================================-----100
echo usage: %~nx0 [/s] [/f pattern] [/x pattern] [/o] [/p prefix] src-dir dest-dir101
echo /s 包含子目录中的文件102
echo /f pattern 需要匹配的文件,多个必须用"+"号分隔,如 *.t*+b??.bat+a*.doc103
echo /x pattern 排除的文件后缀名,多个必须用"+"号分隔,如 bak+tmp104
echo /d 显示以目录为单位,并进行目录双向比较105
echo /q 关闭控制台内容显示106
echo /u 抑制不必要的输出(较慢)107
echo /p prefix 输出文件名的前缀108
echo /o 覆盖原有输出文件109
echo /t 输出html格式的结果文件格式110
echo /c param 传递给FC的参数,多个必须用"+"号分隔,比如/C+/N+/W111
echo /m 脚本生成完毕,运行之前允许用%%EDITOR%%进行修改,默认notepad112
echo /v 运行完毕之后自动打开结果文件113
echo src-dir 用作比较的基准目录114
echo dest-dir 用于比较的目录115
goto end116

117
:start118
if not #%O_OVER%# == #y# goto app119
if exist %PWD%\%O_PRE%-diff.%O_POST% del /f /q %PWD%\%O_PRE%-diff.%O_POST%120
if exist %PWD%\%O_PRE%-same.%O_POST% del /f /q %PWD%\%O_PRE%-same.%O_POST%121
if exist %PWD%\%O_PRE%-lost.%O_POST% del /f /q %PWD%\%O_PRE%-lost.%O_POST%122
if exist %PWD%\%O_PRE%-redu.%O_POST% del /f /q %PWD%\%O_PRE%-redu.%O_POST%123
if exist %PWD%\%O_PRE%-all.%O_POST% del /f /q %PWD%\%O_PRE%-all.%O_POST%124
if exist %PWD%\%O_PRE%-dir.%O_POST% del /f /q %PWD%\%O_PRE%-dir.%O_POST%125
:app126
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-diff.%O_POST%127
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-same.%O_POST%128
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-lost.%O_POST%129
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-redu.%O_POST%130
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-all.%O_POST%131
echo ===============================%DATE% %TIME%=========================== >> %PWD%\%O_PRE%-dir.%O_POST%132

133
set RND=%TIME::=.%-%RANDOM%134
set TEMP_BAT="%TEMP%\myfc-%RND%.bat"135
rem ==========开始生成临时脚本==========136
echo @echo off> %TEMP_BAT%137
echo rem 本文件由myfc.bat自动生成>> %TEMP_BAT%138
echo set SRC=%DIR1%>> %TEMP_BAT%139
echo set DEST=%DIR2%>> %TEMP_BAT%140

141
echo set B_OALL="%PWD%\%O_PRE%-all.%O_POST%">> %TEMP_BAT%142
echo set B_ODIR="%PWD%\%O_PRE%-dir.%O_POST%">> %TEMP_BAT%143
echo set B_ODIFF="%PWD%\%O_PRE%-diff.%O_POST%">> %TEMP_BAT%144
echo set B_OSAME="%PWD%\%O_PRE%-same.%O_POST%">> %TEMP_BAT%145
echo set B_OREDU="%PWD%\%O_PRE%-redu.%O_POST%">> %TEMP_BAT%146
echo set B_OLOST="%PWD%\%O_PRE%-lost.%O_POST%">> %TEMP_BAT%147

148
echo set B_TDIFF="%TEMP%\t%RND%-diff.txt">> %TEMP_BAT%149
echo set B_TSAME="%TEMP%\t%RND%-same.txt">> %TEMP_BAT%150
echo set B_TREDU="%TEMP%\t%RND%-redu.txt">> %TEMP_BAT%151
echo set B_TLOST="%TEMP%\t%RND%-lost.txt">> %TEMP_BAT%152

153
echo pushd %%SRC%%>> %TEMP_BAT%154
echo call:walk_dir "%%SRC%%\">> %TEMP_BAT%155
if "%O_SUB%" == "y" (set T_SUB=/r %%SRC%%) else (set T_SUB=)156
echo for /d %T_SUB% %%%%v in (*.*) do call:walk_dir "%%%%~fv">> %TEMP_BAT%157
set T_SUB=158
echo popd>> %TEMP_BAT%159
echo cd %PWD%>> %TEMP_BAT%160
echo goto :EOF>> %TEMP_BAT%161

162
echo :walk_dir>> %TEMP_BAT%163
if not "%O_QUITE%" == "" goto skip_q1164
echo echo %%1>> %TEMP_BAT%165
:skip_q1166
echo pushd %%1>> %TEMP_BAT%167

168
echo if exist %%B_TSAME%% del /q /f %%B_TSAME%% ^> nul>> %TEMP_BAT%169
echo if exist %%B_TDIFF%% del /q /f %%B_TDIFF%% ^> nul>> %TEMP_BAT%170
echo if exist %%B_TREDU%% del /q /f %%B_TREDU%% ^> nul>> %TEMP_BAT%171
echo if exist %%B_TLOST%% del /q /f %%B_TLOST%% ^> nul>> %TEMP_BAT%172

173
echo for %%%%F in (%O_PAT:+= %) do ( >> %TEMP_BAT%174
if not "%O_QUITE%" == "" goto skip_q2175
echo echo %%%%F>> %TEMP_BAT%176
:skip_q2177
echo set B_EX=>> %TEMP_BAT%178
if "%O_EXC%" == "" goto skip_e1179
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xF" set B_EX=y>> %TEMP_BAT%180
:skip_e1181
echo if "!B_EX!" == "" ( >> %TEMP_BAT%182
echo set B_FN=%%%%~fF>> %TEMP_BAT%183
echo set B_DFN=!B_FN:%DIR1%\=%DIR2%\!>> %TEMP_BAT%184
echo call:out fc %O_CMDL:+= % !B_FN! !B_DFN! ^>^> %%B_OALL%%>> %TEMP_BAT%185
echo if exist "!B_DFN!" ( >> %TEMP_BAT%186
echo call:out %%%%~tF %%%%~zF %%%%~fF ^>^> %%B_OALL%%>> %TEMP_BAT%187
echo for %%%%n in ("!B_DFN!") do ( >> %TEMP_BAT%188
echo call:out %%%%~tn %%%%~zn %%%%~fn ^>^> %%B_OALL%%>> %TEMP_BAT%189
echo )>> %TEMP_BAT%190
echo fc %O_CMDL:+= % "!B_FN!" "!B_DFN!" ^>^> %%B_OALL%%>> %TEMP_BAT%191
echo if #!errorlevel!# == #1# ( >> %TEMP_BAT%192
echo call:out diff "!B_FN!" "!B_DFN!" ^>^> %%B_TDIFF%%>> %TEMP_BAT%193
echo call:out . %%%%~tF %%%%~zF %%%%~fF ^>^> %%B_TDIFF%%>> %TEMP_BAT%194
echo for %%%%n in ("!B_DFN!") do ( >> %TEMP_BAT%195
echo call:out . %%%%~tn %%%%~zn %%%%~fn ^>^> %%B_TDIFF%%>> %TEMP_BAT%196
echo )>> %TEMP_BAT%197
echo )>> %TEMP_BAT%198
echo if #!errorlevel!# == #0# ( >> %TEMP_BAT%199
echo call:out same !B_FN! !B_DFN! ^>^> %%B_TSAME%%>> %TEMP_BAT%200
echo )>> %TEMP_BAT%201
echo ) else ( >> %TEMP_BAT%202
echo call:out lost !B_DFN! ^>^> %%B_OALL%%>> %TEMP_BAT%203
echo call:out lost !B_DFN! ^>^> %%B_TLOST%%>> %TEMP_BAT%204
echo )>> %TEMP_BAT%205
echo )>> %TEMP_BAT%206
echo )>> %TEMP_BAT%207
echo popd>> %TEMP_BAT%208

209
if not "%O_DIR%" == "y" goto skip_d1210
echo set B_SDIR=%%1>> %TEMP_BAT%211
echo set B_DDIR=!B_SDIR:%DIR1%\=%DIR2%\!>> %TEMP_BAT%212
echo if not exist %%B_DDIR%% goto no_redu>> %TEMP_BAT%213
echo pushd %%B_DDIR%%>> %TEMP_BAT%214
echo for %%%%F in (%O_PAT:+= %) do ( >> %TEMP_BAT%215
echo set B_EX=>> %TEMP_BAT%216
if "%O_EXC%" == "" goto skip_e2217
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xF" set B_EX=y>> %TEMP_BAT%218
:skip_e2219
echo if "!B_EX!" == "" ( >> %TEMP_BAT%220
echo set B_1=%%%%~fF>> %TEMP_BAT%221
echo set B_2=!B_1:%DIR2%\=%DIR1%\!>> %TEMP_BAT%222
echo if not exist "!B_2!" ( >> %TEMP_BAT%223
echo call:out redundant "%%%%~fF" ^>^> %%B_TREDU%%>> %TEMP_BAT%224
echo )>> %TEMP_BAT%225
echo )>> %TEMP_BAT%226
echo )>> %TEMP_BAT%227
echo for /d %%%%F in (*.*) do (>> %TEMP_BAT%228
echo set B_1=%%%%~fF>> %TEMP_BAT%229
echo set B_2=!B_1:%DIR2%\=%DIR1%\!>> %TEMP_BAT%230
echo if not exist "!B_2!" call:fnList "%%%%~fF">> %TEMP_BAT%231
echo )>> %TEMP_BAT%232
echo )>> %TEMP_BAT%233
echo popd>> %TEMP_BAT%234
echo goto no_redu>> %TEMP_BAT%235
echo :fnList>> %TEMP_BAT%236
echo for /r %%1 %%%%G in (%O_PAT:+= %) do ( >> %TEMP_BAT%237
echo set B_EX=>> %TEMP_BAT%238
if "%O_EXC%" == "" goto skip_e3239
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xG" set B_EX=y>> %TEMP_BAT%240
:skip_e3241
echo if "!B_EX!" == "" ( >> %TEMP_BAT%242
echo call:out redundant "%%%%~fG" ^>^> %%B_TREDU%%>> %TEMP_BAT%243
echo )>> %TEMP_BAT%244
echo )>> %TEMP_BAT%245
echo goto :EOF>> %TEMP_BAT%246
echo :no_redu>> %TEMP_BAT%247
:skip_d1248

249
echo echo %%1 ^>^> %%B_ODIR%%>> %TEMP_BAT%250

251
echo if exist %%B_TSAME%% type %%B_TSAME%% ^>^> %%B_OSAME%%>> %TEMP_BAT%252
echo if exist %%B_TDIFF%% type %%B_TDIFF%% ^>^> %%B_ODIFF%%>> %TEMP_BAT%253
echo if exist %%B_TREDU%% type %%B_TREDU%% ^>^> %%B_OREDU%%>> %TEMP_BAT%254
echo if exist %%B_TLOST%% type %%B_TLOST%% ^>^> %%B_OLOST%%>> %TEMP_BAT%255

256
echo if exist %%B_TSAME%% type %%B_TSAME%% ^>^> %%B_ODIR%%>> %TEMP_BAT%257
echo if exist %%B_TDIFF%% type %%B_TDIFF%% ^>^> %%B_ODIR%%>> %TEMP_BAT%258
echo if exist %%B_TREDU%% type %%B_TREDU%% ^>^> %%B_ODIR%%>> %TEMP_BAT%259
echo if exist %%B_TLOST%% type %%B_TLOST%% ^>^> %%B_ODIR%%>> %TEMP_BAT%260

261
echo if exist %%B_TSAME%% del /q /f %%B_TSAME%% ^> nul>> %TEMP_BAT%262
echo if exist %%B_TDIFF%% del /q /f %%B_TDIFF%% ^> nul>> %TEMP_BAT%263
echo if exist %%B_TREDU%% del /q /f %%B_TREDU%% ^> nul>> %TEMP_BAT%264
echo if exist %%B_TLOST%% del /q /f %%B_TLOST%% ^> nul>> %TEMP_BAT%265

266
echo goto end>> %TEMP_BAT%267
echo :out>> %TEMP_BAT%268
echo echo %%*>> %TEMP_BAT%269
echo goto :EOF>> %TEMP_BAT%270

271
echo :end>> %TEMP_BAT%272
rem ==========临时脚本生成完毕==========273

274
set FN=275

276
if "%O_MODI%" == "y" start "edit before run %TEMP_BAT%" /wait "%P_EDTR%" %TEMP_BAT%277
cmd.exe /V:ON /C %TEMP_BAT%278

279
set FN=280

281
del /f /q %TEMP_BAT%282
set TEMP_BAT=283

284
if "%O_VIEW%"=="y" (285
if exist %PWD%\%O_PRE%-diff.%O_POST% start "view" %PWD%\%O_PRE%-diff.%O_POST%286
if exist %PWD%\%O_PRE%-same.%O_POST% start "view" %PWD%\%O_PRE%-same.%O_POST%287
if exist %PWD%\%O_PRE%-lost.%O_POST% start "view" %PWD%\%O_PRE%-lost.%O_POST%288
if exist %PWD%\%O_PRE%-redu.%O_POST% start "view" %PWD%\%O_PRE%-redu.%O_POST%289
if exist %PWD%\%O_PRE%-all.%O_POST% start "view" %PWD%\%O_PRE%-all.%O_POST%290
if exist %PWD%\%O_PRE%-dir.%O_POST% start "view" %PWD%\%O_PRE%-dir.%O_POST%291
)292
goto end293

294
:end295
set DEBUG=296
set CMDLINE=297
set PWD=298
set DIR1=299
set DIR2=300
set DIR1S=301
set DIR2S=302
set RND=303

304
set O_SUB=305
set O_PAT=306
set O_DIR=307
set O_SUP=308
set O_OVER=309
set O_VIEW=310
set O_PRE=311
set O_CMDL=312
set O_EXC=313
set O_MODI=314
set O_POST=315
set O_QUITE=316
set P_EDTR=317

318
set SRC=319
set DEST=320
set B_1=321
set B_2=322
set B_DDIR=323
set B_OALL=324
set B_ODIFF=325
set B_ODIR=326
set B_OLOST=327
set B_OREDU=328
set B_OSAME=329
set B_SDIR=330
set B_TDIFF=331
set B_TLOST=332
set B_TREDU=333
set B_TSAME=334

