因为工作需要,对遗留项目进行规范化整理,面对多个不同版本的程序,如何整理出一个完整的有效的代码?目前的工具比如ultra compare或者号称最好用的beyond compare,具有的只是目录比较和文件比较功能,其中目录比较只是简单比较文件的属性差异,不会比较目录中各个文件的差异,所以用了几天时间,修改完善了我自己的myfc,一个纯批处理文件,具有的功能如下:
1.比较两个目录的差异,支持目录的递归比较,判断标准是文件内容是否相同。
2.生成标准化的结果报告
小技巧:
1.如果加入-d参数,则会把所有的比较结果按照目录为单位输出到一个文件中。
2.对于*-diff.txt文件,可以用查找替换,把它变成一个bat文件,可以对有差异的文件用更高级的比较器进行比较。我经常会把diff.txt中的diff替换成call bc /w ,把 . 替换成rem,然后另存为bat格式。如果大家有要求,我考虑把它变成一个标准的输出格式
目前尚未实现的功能:
1. 除了文本之外的其他输出格式支持,比如xml或html的输出格式
下载代码如下:

Code
1
@echo off
2
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=a
18
if "!TSTEXT!"=="a" cmd.exe /V:OFF /C %0 %* & exit /b
19
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=on
28
if #%1# == #debug# set DEBUG=on
29
if #%DEBUG%# == #on# set CMDLINE=%CMDLINE0:~5%
30
if NOT #%DEBUG%# == #on# set CMDLINE=%CMDLINE0%
31
set CMDLINE0=
32
if #%DEBUG%# == #on# shift
33
@if #%DEBUG%# == #on# @echo on
34
35
rem 是否显示帮助
36
if "%1" == "" goto help
37
if "%1" == "/?" goto help
38
if "%1" == "-?" goto help
39
if "%1" == "?" goto help
40
for %%a in (help HELP /help /HELP -help -HELP --help --HELP h H /h /H -h -H --h --H ) do if "%1" == "%%a" goto help
41
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-o
53
set O_OVER=
54
set O_POST=txt
55
set O_CMDL=/n+/w
56
set O_MODI=
57
set O_VIEW=
58
if "%EDITOR%"=="" (set P_EDTR=notepad.exe) else (set P_EDTR=%EDITOR%)
59
60
:opt_an
61
for %%a in ( /s -s /S -S ) do if "%1" == "%%a" set O_SUB=y&& goto opt_nx
62
for %%a in ( /f -f /F -F ) do if "%1" == "%%a" goto opt_pat
63
for %%a in ( /x -x /X -X ) do if "%1" == "%%a" goto opt_exc
64
for %%a in ( /d -d /D -D ) do if "%1" == "%%a" set O_DIR=y&& goto opt_nx
65
for %%a in ( /q -q /Q -Q ) do if "%1" == "%%a" set O_QUITE=y&& goto opt_nx
66
for %%a in ( /u -u /U -U ) do if "%1" == "%%a" set O_SUP=y&& goto opt_nx
67
for %%a in ( /p -p /P -P ) do if "%1" == "%%a" goto opt_pre
68
for %%a in ( /o -o /O -O ) do if "%1" == "%%a" set O_OVER=y&& goto opt_nx
69
for %%a in ( /t -t /T -T ) do if "%1" == "%%a" set O_POST=htm&& goto opt_nx
70
for %%a in ( /c -c /C -C ) do if "%1" == "%%a" goto opt_cmd
71
for %%a in ( /m -m /M -M ) do if "%1" == "%%a" set O_MODI=y&& goto opt_nx
72
for %%a in ( /v -v /V -V ) do if "%1" == "%%a" set O_VIEW=y&& goto opt_nx
73
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_nx
75
:opt_pat
76
shift
77
set O_PAT=%1
78
goto opt_nx
79
:opt_exc
80
shift
81
set O_EXC=%1
82
goto opt_nx
83
:opt_cmd
84
shift
85
set O_CMDL=%1
86
goto opt_nx
87
:opt_pre
88
shift
89
set O_PRE=%1
90
:opt_nx
91
shift
92
if not "%1" == "" goto opt_an
93
94
if "%DIR1%" == "" goto help
95
if "%DIR2%" == "" goto help
96
goto start
97
98
:help
99
echo -----======================================================================-----
100
echo usage: %~nx0 [/s] [/f pattern] [/x pattern] [/o] [/p prefix] src-dir dest-dir
101
echo /s 包含子目录中的文件
102
echo /f pattern 需要匹配的文件,多个必须用"+"号分隔,如 *.t*+b??.bat+a*.doc
103
echo /x pattern 排除的文件后缀名,多个必须用"+"号分隔,如 bak+tmp
104
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+/W
111
echo /m 脚本生成完毕,运行之前允许用%%EDITOR%%进行修改,默认notepad
112
echo /v 运行完毕之后自动打开结果文件
113
echo src-dir 用作比较的基准目录
114
echo dest-dir 用于比较的目录
115
goto end
116
117
:start
118
if not #%O_OVER%# == #y# goto app
119
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
:app
126
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_q1
164
echo echo %%1>> %TEMP_BAT%
165
:skip_q1
166
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_q2
175
echo echo %%%%F>> %TEMP_BAT%
176
:skip_q2
177
echo set B_EX=>> %TEMP_BAT%
178
if "%O_EXC%" == "" goto skip_e1
179
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xF" set B_EX=y>> %TEMP_BAT%
180
:skip_e1
181
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_d1
210
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_e2
217
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xF" set B_EX=y>> %TEMP_BAT%
218
:skip_e2
219
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_e3
239
echo for %%%%e in (%O_EXC:+= %) do if "!B_EX!"=="" if ".%%%%e" == "%%%%~xG" set B_EX=y>> %TEMP_BAT%
240
:skip_e3
241
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_d1
248
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 end
293
294
:end
295
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