当前位置: 首页 > 图文教程 > 脚本技术 > DOS/BAT > 批处理方式实现的目录比较工具

DOS/BAT
每天按时 重启服务器 的批处理
Netsh 命令备份和恢复网络设置
批处理 Set 命令详解 让你理解set命令
cd命令 目录跳转
cmd tree命令 以树形格式罗列文件
dos 内容重定向符 >和>>
cmd if条件 条件判断
cmd goto命令 流程跳转
cmd copy命令 文件复制
cmd del命令 文件删除
cmd ren命令 重命名文件(夹)
cmd md命令 创建文件夹
cmd rd命令 删除文件夹
cmd move命令 移动文件(夹)
字符串查找 cmd find命令
常用的批处理实用技巧
批处理 添加隐藏用户代码
服务器 安全设置 批处理
WIN2003 服务器安全配置批处理文件
批处理 实现定时关机、注销、重启、锁定等功能

DOS/BAT 中的 批处理方式实现的目录比较工具


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-11   浏览: 53 ::
收藏到网摘: n/a

更新日志:
v4:
1.增加了计算的进度显示;
2.找了新版的 md5sum.exe,没有对动态库的依赖。
工具一:md5comv4.bat 接受两个目录参数,计算两个目录里每个文件的 md5 值,并给出报表文件 md5v4.txt,使用方法:
md5omv4.bat <目录1> <目录2>
根据这 md5comv4.bat 生成的报表文件 md5v4.txt,可以找到两个目录中
1:同名而且 md5 相同的文件;
2:同名但是 md5 不同的文件;
3:不同名但是 md5 相同的文件;
4:同一目录中不同名但是 md5 相同的文件。
注意事项:
1:md5comv4.bat 不接受路径带有空格的目录名,但是可以接受带有空格的文件名;
2:md5 的计算由 md5sum.exe 完成;
3:md5comv4.bat 运行时会产生大量临时文件,这些文件由工具自动维护,不必手工清理。
这个工具都是命令行方式、文本界面的,对于习惯使用图形界面的朋友来说,可能不方便,因此,不推荐习惯使用图形界面的朋友使用。
复制代码 代码如下:

@echo off
setlocal enableextensions enabledelayedexpansion
rem 作者:[email protected]
rem 17:55 2009-4-14 版本:0.4
set dira=%~1
set dirb=%~2
if "%1" == "" (
echo 使用说明:请在命令行参数上指明两个目录,或在这里按提示输入。
echo 命令行参数格式:批处理名 ^<目录1^> ^<目录2^>
echo.
set /p dira=请输入第一个目录的名字(可拖放并输入回车):
)
echo.
if "%2" == "" (
echo 使用说明:请在命令行参数上指明两个目录,或在这里按提示输入。
echo 命令行参数格式:批处理名 ^<目录1^> ^<目录2^>
echo.
set /p dirb=请输入第二个目录的名字(可拖放并输入回车):
)
if "%dira%" == "" exit /b
if "%dirb%" == "" exit /b
for /F "delims=. tokens=1" %%A in ("%TIME%") do set startTime=%%A
for /F "delims=: tokens=1,2,3" %%A in ("%startTime%") do (
set startH=%%A
set startM=%%B
set startS=%%C
)
set TEMPDIR=TEMPMD5\
rd /Q /S %TEMPDIR% 1>NUL 2>NUL
md %TEMPDIR%
set mdfive=md5v4.txt
rem 已处理的文件数
set count=0
rem 文件夹 %dira% 和 %dirb% 里的文件总数
set total_count=0
rem 已处理的临时文件数
set tmpf_count=0
rem 临时文件总数,已知有 5 个了。其余的是 md5 值的个数
set tmpf_total_count=5
echo 第 1/2步,正在计算,请稍候……
echo 正在比较 %dira% 和 %dirb% 中的文件的 md5 值 > %mdfive%
set list_fn_md=%TEMPDIR%list_fn_md
set list_fn_nmd=%TEMPDIR%list_fn_nmd
set list_fn_oa=%TEMPDIR%list_fn_oa
set list_fn_ob=%TEMPDIR%list_fn_ob
set list_all_md=%TEMPDIR%list_all_md
call :COUNTFILES %dira%
call :COUNTFILES %dirb%
for /f "delims=" %%a in ('dir /b /a:-d "%dira%\*"') do (
set fn=%%~nxa
for /f "tokens=1 delims= " %%A in ('md5sum "%dira%\%%a"') do set mda=%%A
set /a count=!count!+1
call :PROGRESS !count! !total_count!
if "!mda:~0,1!" == "\" set mda=!mda:~1,1024!
rem 以 !mda! 为文件名,记录 md5 为 !mda! 的文件
call :ADDMDFN "%TEMPDIR%!mda!" "%dira%\!fn!"
rem 把 md5 值记录到文件里,保证不重复
call :ADDMDLIST !mda!
if exist "%dirb%\!fn!" (
for /f "tokens=1 delims= " %%A in ('md5sum "%dirb%\!fn!"') do set mdb=%%A
set /a count=!count!+1
call :ADDMDFN "%TEMPDIR%!mdb!" "%dirb%\!fn!"
call :PROGRESS !count! !total_count!
if "!mdb:~0,1!" == "\" set mdb=!mdb:~1,1024!
if "!mda!" == "!mdb!" (
rem 记录文件名相同并且 md5 相同的文件
echo !mda! !mdb! !fn! >> "!list_fn_md!"
) else (
rem 记录文件名相同但 md5 不相同的文件
echo !mda! !mdb! !fn! >> "!list_fn_nmd!"
call :ADDMDLIST !mdb!
)
) else (
rem 记录只在 %dira% 中出现的文件
echo !mda! !fn! >> "!list_fn_oa!"
)
)
for /f "delims=" %%a in ('dir /b /a:-d "%dirb%\*"') do (
set fn=%%~nxa
if not exist "%dira%\!fn!" (
for /f "tokens=1 delims= " %%A in ('md5sum "%dirb%\%%a"') do set mdb=%%A
if "!mdb:~0,1!" == "\" set mdb=!mdb:~1,1024!
rem 记录只在 %dirb% 中出现的文件
echo !mdb! !fn! >> "!list_fn_ob!"
rem 把 md5 值记录到文件里,保证不重复
call :ADDMDLIST !mdb!
call :ADDMDFN "%TEMPDIR%!mdb!" "%dirb%\!fn!"
set /a count=!count!+1
call :PROGRESS !count! !total_count!
)
)
echo 第 2/2步,正在统计,请稍候……
echo 统计:>>%mdfive%
echo 左:%dira% >> %mdfive%
echo 右:%dirb% >> %mdfive%
if not exist "%list_fn_md%" set /a tmpf_total_count-=1
if not exist "%list_fn_nmd%" set /a tmpf_total_count-=1
if not exist "%list_fn_oa%" set /a tmpf_total_count-=1
if not exist "%list_fn_ob%" set /a tmpf_total_count-=1
if not exist "%list_all_md%" set /a tmpf_total_count-=1
echo 两个目录中都存在且 md5 相同的文件:>> %mdfive%
call :OUTPUTLIST "%list_fn_md%"
echo ===============================================================================================>> %mdfive%
echo 左:%dira% >> %mdfive%
echo 右:%dirb% >> %mdfive%
echo 两个目录中都存在但 md5 不相同的文件:>> %mdfive%
call :OUTPUTLIST "%list_fn_nmd%"
echo ===============================================================================================>> %mdfive%
echo 只在目录 %dira% 中存在的文件:>> %mdfive%
call :OUTPUTLIST "%list_fn_oa%"
echo ===============================================================================================>> %mdfive%
echo 只在目录 %dirb% 中存在的文件:>> %mdfive%
call :OUTPUTLIST "%list_fn_ob%"
echo ===============================================================================================>> %mdfive%
echo 以 md5 汇总的文件列表:>> %mdfive%
call :OUTPUTLIST_MD "%list_all_md%"
goto ALLDONE
rem 统计文件夹里的文件数目,放到全局变量 total_count 里
:COUNTFILES
if %1=="" goto :EOF
for /f %%a in ('dir /b /a:-d "%~1\*"') do (
set /a total_count=!total_count!+1
)
goto :EOF
rem 参数 %1 必须加双引号
:OUTPUTLIST
if %1 == "" goto :EOF
if not exist %1 goto :EOF
set tcnt=0
for /f "tokens=1* delims= " %%a in (%~1) do (
echo %%a %%b >> %mdfive%
set /a tcnt+=1
)
echo !tcnt! >> %mdfive%
set /a tmpf_count+=1
call :PROGRESS !tmpf_count! !tmpf_total_count!
goto :EOF
rem 参数 %1 必须加双引号
:OUTPUTLIST_MD
if %1 == "" goto :EOF
if not exist %1 goto :EOF
set /a tmpf_count+=1
call :PROGRESS !tmpf_count! !tmpf_total_count!
set md_count=0
for /f "tokens=1* delims= " %%a in (%~1) do (
echo %%a >> %mdfive%
set tcnt=0
for /f "tokens=1* delims= " %%A in (!TEMPDIR!%%a) do (
echo %%A %%B >> %mdfive%
set /a tcnt+=1
)
set /a tmpf_count+=1
call :PROGRESS !tmpf_count! !tmpf_total_count!
echo !tcnt! >> %mdfive%
set /a md_count+=1
echo. >> %mdfive%
)
echo %md_count% >> %mdfive%
goto :EOF
rem 函数:把 md5 值保存到一个名为 !list_all_md! 的文件里,
rem 并保证不保存重复的 md5 值
:ADDMDLIST
if %1 == "" goto :EOF
if exist "!list_all_md!" (
rem 这里的 delims 要么删除,要么做成像下面这行的样子,在等号后面加个空格
rem for /f "tokens=1 delims= " %%a in (!list_all_md!) do (
for /f "tokens=1 " %%a in (!list_all_md!) do (
if "%%a" == "%1" goto :EOF
)
)
echo %1 >> "!list_all_md!"
rem 记录临时文件总数
set /a tmpf_total_count+=1
goto :EOF
rem 函数:以 %1 为文件名,保存 %2
rem %1:在这个应用里是 md5 值
rem %2:md5 值为 %1 的文件
:ADDMDFN
if %1 == "" goto :EOF
if %2 == "" goto :EOF
echo %2 >> %1
goto :EOF
:PROGRESS
set tips=
set backspace=
set /a percent=%1*100/%2
set /a char=%1%%7
set /a bnum=%percent%/10
set /a snum=10-%bnum%
for /L %%a in (1, 1, %bnum%) do set /p=▌<NUL
for /L %%a in (1, 1, %snum%) do set /p= <NUL
set /p=%1/%2 %percent%%% <NUL
set /p=!tips:~%char%,1!<NUL
if "%percent%" == "100" (
echo.
goto :EOF
)
set /p=%backspace%<NUL
goto :EOF
rem :PROGRESS
rem set tips=
rem set backspace=
rem set /a char=%1%%7
rem set /p=!tips:~%char%,1!<NUL
rem set /p=%backspace%<NUL
rem goto :EOF
:ALLDONE
rd /Q /S %TEMPDIR% 1>NUL 2>NUL
for /F "delims=. tokens=1" %%A in ("%TIME%") do set endTime=%%A
for /F "delims=: tokens=1,2,3" %%A in ("%endTime%") do (
set endH=%%A
set endM=%%B
set endS=%%C
)
if "%endM:~0,1%" == "0" set endM=%endM:~1,1%
if "%endS:~0,1%"=="0" set endS=%endS:~1,1%
for /F "delims=: tokens=1,2,3" %%A in ("%startTime%") do (
set startH=%%A
set startM=%%B
set startS=%%C
)
if "%startM:~0,1%"=="0" set startM=%startM:~1,1%
if "%startS:~0,1%"=="0" set startS=%startS:~1,1%
set /A totalTime=%endH%*3600+%endM%*60+%endS%-(%startH%*3600+%startM%*60+%startS%)
echo 共用时 %totalTime% 秒。
echo 起始时间:%startH%:%startM%:%startS%>>%mdfive%
echo 结束时间:%endH%:%endM%:%endS%>>%mdfive%
echo 共用时 %totalTime% 秒。>>%mdfive%
start %mdfive%
echo 
endlocal
@echo on

文件打包下载