posts - 41,  comments - 40,  trackbacks - 0

          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: Name: 搜索重復圖片(或其他任意類型、大小的文件,對0字節的也比較)
          ::
          :: Author: NeedJava
          ::
          :: Modified: 2007-07-30
          ::
          :: 注意:你可以在任何地方使用此批處理,但必須保持文件作者及注釋部分的完整
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          @ECHO OFF

          SETLOCAL EnableDelayedExpansion

          ECHO 搜索重復的圖片,按任意鍵繼續。
          ECHO.

          PAUSE>NUL

          DEL /F /Q hash.txt 2>NUL
          DEL /F /Q sort.txt 2>NUL
          DEL /F /Q clone.txt 2>NUL
          DEL /F /Q lost.txt 2>NUL

          RD /S /Q "Clone\" 2>NUL & MD "Clone\" 2>NUL


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 生成“文件大小|文件路徑”,再排序,內容諸如:
          ::
          :: 25329|C:\Documents and Settings\Administrator\桌面\02.jpg
          ::
          :: 把文件大小加上100000000,即100MB,這樣方便SORT命令比較大小,那么內容變成如下:
          ::
          :: 100025329|C:\Documents and Settings\Administrator\桌面\02.jpg
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          CLS

          ECHO 正在搜索文件,請稍候……
          ECHO.

          FOR /R %%a IN ( *.jpg ) DO (

          ??? SET /A size=%%~za+100000000

          ??? ECHO !size!^|%%a>>hash.txt

          )


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 根據列表每行前面所列出的文件大小進行排序
          ::
          :: 把文件大小加上100000000,即100MB,這樣方便SORT命令比較大小
          ::
          :: 否則SORT會給我們“1、123、1235、2、21、3”這樣的順序
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          CLS

          ECHO 正在排序文件,請稍候……
          ECHO.

          IF EXIST hash.txt (

          ?? SORT /R hash.txt /O sort.txt 2>NUL

          )


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 把大小相同的文件分離成一個個單獨的文件,方便后面的相互比較
          ::
          :: 我不認為需要對5MB以上的圖片文件進行二進制比較,它們夠顯眼的了
          ::
          :: 只有大小一樣才需要作進一步的二進制比較,否則就是搞笑了
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          CLS

          ECHO 正在分離文件,請稍候……
          ECHO.

          IF EXIST sort.txt (

          ?? SET "preSize="

          ?? SET "preFile="

          ?? FOR /F "tokens=1,2 delims=|" %%a IN ( sort.txt ) DO (

          ?????? SET /A curSize=%%a-100000000

          ?????? SET "curFile=%%b"

          ?????? IF NOT "!preFile!"=="" IF !preSize! LEQ 5000000 (

          ????????? IF !preSize! EQU !curSize! (

          ???????????? IF /I NOT "!always!"=="true" (

          ??????????????? ECHO !preSize!^|!preFile!>"Clone\!preSize!.vab"

          ??????????????? SET "always=true"

          ???????????? )

          ???????????? ECHO !curSize!^|!curFile!>>"Clone\!preSize!.vab"

          ????????? ) ELSE (

          ??????????? SET "always=false"

          ????????? )

          ?????? )

          ?????? SET /A preSize=!curSize!

          ?????? SET "preFile=!curFile!"

          ?? )

          )


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 微軟一些DOS命令的搞笑BUG:
          ::
          :: FC:名稱的字數超過185個的文件夾不予理會
          ::
          :: DIR:把路徑中的一些Unicode碼(如30FB)用半角問號“?”代替,記事本也如此
          ::
          :: FOR /R:不但把Unicode碼(如30FB)用半角問號“?”代替,還會刪除路徑中的“!”和“^”
          ::
          :: 以上這些微軟BUG,使這個批處理也有了BUG:路徑中不能有“!”、“^”和一些Unicode碼
          ::
          ::
          :: FC命令返回代碼含義:
          ::
          :: 0?? 完全相同
          ::
          :: 1?? 不完全同
          ::
          :: 2?? 缺少文件
          ::
          ::
          :: FIND命令返回代碼含義:
          ::
          :: 0?? 找到字符串
          ::
          :: 1?? 沒有找到字符串
          ::
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          :reload

          IF EXIST "Clone\" (

          ?? FOR /R "Clone\" %%a IN ( *.vab ) DO (

          ?????? SET "list=Clone\%%~nxa"

          ?????? SET /A num=1

          ?????? GOTO cycle

          ?? )

          )

          GOTO delete


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 原理:
          ::
          :: 假設有DATA[A B C D B A A]這個7位數組需要自身比較,按照正常的方法,如下:
          ::
          :: for( int i=0; i<n-1; i++ )
          ::??? {
          ::????? for( int j=i+1; j<n; j++ )
          ::???????? {
          ::?????????? compare DATA[i] DATA[j]...
          ::???????? }
          ::??? }
          ::
          :: 需要比較N*(N-1)/2次,即7*(7-1)/2=21次,如下:
          ::
          :: [A B]、[A C]、[A D]、[A B]、[A A]、[A A]
          ::
          :: [B C]、[B D]、[B B]、[B A]、[B A]
          ::
          :: [C D]、[C B]、[C A]、[C A]
          ::
          :: [D B]、[D A]、[D A]
          ::
          :: [B A]、[B A]
          ::
          :: [A A]
          ::
          :: 但是從上面的列表可以發現,有些已經被確定和某個數相同的數,如[A]和[B]兩類,
          ::
          :: 在后面依然和別的數繼續比較,這是不科學的,應該在找到相同類后,刪除它們。
          ::
          :: 也就是說,一旦找到相同的類,就把它們剔除出循環,那么循環應該如下:
          ::
          :: A B C D B A A
          ::
          :: 第一次循環找出所有相同的[A]后,待比較列表動態變為:
          ::
          :: B C D B
          ::
          :: 第二次循環找出所有相同的[B]后,待比較列表動態變為:
          ::
          :: C D
          ::
          :: 如上,那么比較為:
          ::
          :: [A B]、[A C]、[A D]、[A B]、[A A]、[A A]
          ::
          :: [B C]、[B D]、[B B]、[BXA]、[BXA]
          ::
          :: [C D]、[CXB]、[CXA]、[CXA]
          ::
          :: [DXB]、[DXA]、[DXA]
          ::
          :: [BXA]、[BXA]
          ::
          :: [AXA]
          ::
          :: 中間有X的表示已被縮減的,即最終比較為:
          ::
          :: [A B]、[A C]、[A D]、[A B]、[A A]、[A A]
          ::
          :: [B C]、[B D]、[B B]
          ::
          :: [C D]
          ::
          :: 整個批處理原理:
          ::
          :: 1、FOR命令通過%%~za生成零散的,每列開頭為文件大小的文件列表hash.txt,如:
          ::
          ::??? 100017000|E:\123.jpg
          ::??? 100017000|E:\345.jpg
          ::??? 100056732|E:\ffff.jpg
          ::??? 100017000|E:\OK\123.jpg
          ::??? 100056732|E:\OK\ffff.jpg
          ::??? 100012345|E:\OK\gag.jpg
          ::
          :: 2、SORT命令將hash.txt從大到小(當然也可以從小到大)排序成sort.txt,如:
          ::
          ::??? 100056732|E:\ffff.jpg
          ::??? 100056732|E:\OK\ffff.jpg
          ::??? 100017000|E:\123.jpg
          ::??? 100017000|E:\345.jpg
          ::??? 100017000|E:\OK\123.jpg
          ::??? 100012345|E:\OK\gag.jpg
          ::
          :: 3、分析sort.txt列表文件,如果有兩行以上大小相同的紀錄,分離到同一個新列表文件:
          ::
          ::??? 文件名:Clone\56732.vab,內容如下:
          ::??? 100056732|E:\ffff.jpg
          ::??? 100056732|E:\OK\ffff.jpg
          ::
          ::??? 文件名:Clone\17000.vab,內容如下:
          ::??? 100017000|E:\123.jpg
          ::??? 100017000|E:\345.jpg
          ::??? 100017000|E:\OK\123.jpg
          ::
          :: 4、通過雙層嵌套FOR命令,進行比較,相同的紀錄進clone.txt,也就是最終文件;
          ::
          ::??? 不相同的則紀錄進新的文件comparedN.vab,此處N為數字1、2、3、4,如果不刪除,
          ::
          ::??? 可以看到動態的待比較列表,用于調試。
          ::
          ::??? 一旦生成了comparedN.vab文件,就表示有未比較的文件,則將待比較列表list設成
          ::
          ::??? 最新的comparedN.vab文件,并且跳轉到雙層嵌套FOR命令開頭cycle,重新循環。
          ::
          ::??? 一旦待比較列表list消失,則表明此類大小的文件比較完畢,跳轉到reload,分析下
          ::
          ::??? 一個大小的文件列表。
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          :cycle

          REM TYPE !list! & PAUSE

          IF EXIST !list! (

          ?? FOR /F "tokens=1,2 delims=|" %%M IN ( !list! ) DO (

          ?????? SET "found=false"

          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM??? ::
          REM??? :: 我們分析的文件內容是用“|”分隔的,如下:
          REM??? ::
          REM??? :: 56732|E:\ffff.jpg
          REM??? ::
          REM??? :: tokens=1,2 delims=|會把內容分割成兩部分,即56732和E:\ffff.jpg
          REM??? ::
          REM??? :: 第一個部分用變量%%m表示,也就是文件大小56732
          REM??? ::
          REM??? :: 第二個部分用變量%%n表示,也就是文件完整的路徑E:\ffff.jpg
          REM??? ::
          REM??? :: skip=1表示跳過一行,用來防止自身比較。當然為了穩妥,下面還是用了判斷
          REM??? ::
          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ?????? FOR /F "skip=1 tokens=1,2 delims=|" %%m IN ( !list! ) DO (

          REM??????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM??????? ::
          REM??????? :: 必須是大小相同的文件才能比較。不是必要,但穩妥起見還是判斷一下
          REM??????? ::
          REM??????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ?????????? IF /I "%%M"=="%%m" (

          REM?????????? ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM?????????? ::
          REM?????????? :: 不能自己跟自己比較。雖然上面用skip=1跳過,但穩妥起見還是判斷一下
          REM?????????? ::
          REM?????????? ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ????????????? IF /I NOT "%%N"=="%%n" (

          ???????????????? CLS

          ???????????????? ECHO 正在比較以下%%M字節的兩個文件:
          ???????????????? ECHO %%N
          ???????????????? ECHO %%n
          ???????????????? ECHO.

          REM????????????? PAUSE

          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM????????????? ::
          REM????????????? :: 根據FC命令用二進制比較,所返回的錯誤碼來判斷兩個文件是否相同
          REM????????????? ::
          REM????????????? :: Windows 2000下FC命令有問題,所以Windows 2000不能使用此批處理
          REM????????????? ::
          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ???????????????? FC.EXE /B "%%N" "%%n">NUL 2>NUL

          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM????????????? ::
          REM????????????? :: 兩個文件比較后完全相同,FC命令會返回0
          REM????????????? ::
          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ???????????????? IF !ERRORLEVEL! EQU 0 (

          ??????????????????? ECHO 兩個文件完全相同!
          ??????????????????? ECHO.

          REM???????????????? PAUSE

          REM???????????????? ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM???????????????? ::
          REM???????????????? :: 如果!found!為true,就表示在比較循環中,遇到了第一次相同
          REM???????????????? ::
          REM???????????????? :: 用于在找到的列表clone.txt中寫入新的標題
          REM???????????????? ::
          REM???????????????? ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ??????????????????? IF /I NOT "!found!"=="true" (

          ?????????????????????? ECHO [%%M Bytes]>>clone.txt
          ?????????????????????? ECHO %%N>>clone.txt

          ?????????????????????? SET "found=true"

          ??????????????????? )

          ??????????????????? ECHO %%n>>clone.txt

          ???????????????? )

          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM????????????? ::
          REM????????????? :: 兩個文件比較后不相同,FC命令會返回1
          REM????????????? ::
          REM????????????? :: 把不相同的文件寫入下一個待比較列表
          REM????????????? ::
          REM????????????? :: 這個列表將取代現有列表用于下次循環
          REM????????????? ::
          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ???????????????? IF !ERRORLEVEL! EQU 1 (

          REM???????????????? ECHO %%n & ECHO. & PAUSE

          ??????????????????? ECHO %%m^|%%n>>"compared!num!.vab"

          ???????????????? )

          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM????????????? ::
          REM????????????? :: 找不到相應的文件時,FC命令會返回2
          REM????????????? ::
          REM????????????? :: 由于FOR /R命令得出的路徑,會刪除路徑中的“!”和“^”,
          REM????????????? ::
          REM????????????? :: 這會導致雖然待比較列表有路徑(錯誤的),然而FC命令卻找不到
          REM????????????? ::
          REM????????????? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ???????????????? IF !ERRORLEVEL! EQU 2 (

          REM???????????????? ECHO %%n & ECHO. & PAUSE

          ??????????????????? IF NOT EXIST "%%N" (

          ?????????????????????? ECHO %%M^|%%N>>lost.txt

          ??????????????????? )

          ??????????????????? IF NOT EXIST "%%n" (

          ?????????????????????? ECHO %%m^|%%n>>lost.txt

          ??????????????????? )

          ???????????????? )

          ????????????? )

          ?????????? )

          ?????? )

          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM??? ::
          REM??? :: 如果!found!為true,就表示在這次循環中找到了相同文件
          REM??? ::
          REM??? :: 那么針對這次循環的結束,在找到的列表clone.txt中追加一個空行,用來分隔
          REM??? ::
          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ?????? IF /I "!found!"=="true" (

          ????????? ECHO.>>clone.txt

          ?????? )

          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM??? ::
          REM??? :: 刪除現有的待比較列表,必須刪除,否則會陷入死循環
          REM??? ::
          REM??? :: 這也是跳出循環的判斷條件,very important!
          REM??? ::
          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ?????? DEL /F /Q "!list!" 2>NUL

          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          REM??? ::
          REM??? :: 如果剛才的循環,有一些文件不相同,就會存在新的待比較列表
          REM??? ::
          REM??? :: 我們把它設為新的待比較列表,準備跳轉到循環開頭,重新循環
          REM??? ::
          REM??? :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ?????? IF EXIST "compared!num!.vab" (

          ????????? SET "list=compared!num!.vab"

          ????????? SET /A num+=1

          ?????? ) ELSE (

          ???????? GOTO reload

          ?????? )

          ?????? GOTO cycle

          ?? )

          )


          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          ::
          :: 刪除用過的文件
          ::
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
          :delete

          DEL /F /Q hash.txt 2>NUL
          DEL /F /Q sort.txt 2>NUL

          RD /S /Q "Clone\" 2>NUL

          IF EXIST clone.txt %SystemRoot%\NOTEPAD.EXE clone.txt

          @ECHO ON

          posted on 2007-07-30 13:20 NeedJava 閱讀(639) 評論(0)  編輯  收藏 所屬分類: DOS Windows
          主站蜘蛛池模板: 冕宁县| 静海县| 黄浦区| 龙南县| 岗巴县| 仙居县| 武夷山市| 叙永县| 会同县| 汤阴县| 鹰潭市| 江源县| 盐津县| 阿克陶县| 峨眉山市| 浦城县| 白水县| 马鞍山市| 建平县| 常德市| 启东市| 三原县| 特克斯县| 灵武市| 天水市| 永康市| 郸城县| 隆子县| 静宁县| 琼中| 翼城县| 洮南市| 广昌县| 青冈县| 阜阳市| 南汇区| 广西| 芒康县| 永春县| 搜索| 宜君县|