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

DOS/BAT
批处理制作照片整理器
可以生成SLEEP.EXE的延时命令的bat文件
用bat批量创建文件夹
bat批处理实现的创建10个文件夹,文件夹再包含5个空文件夹
bat延时执行命令的另一种方法
windows服务操作之删除服务 批处理实现
批处理 远程控制
使用批处理修改web打印设置笔记 适用于IE
批处理 结束麦咖啡进程的代码
cmd fsutil 命令新建空文本文件
cmd Tasklist与Tskill管理Windows系统进程
批处理 正则表达式(findstr) 整理
bat 文件 学习使用指南
for 语句从入门到精通
dos 目录跳转 cd
tree 以树形格式罗列文件
dos 内容重定向
dos if 条件判断
dos 流程跳转 goto
dos 文件复制 copy命令

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-11   浏览: 61 ::
收藏到网摘: 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

文件打包下载