2

我想编写一个批处理文件,以两种方式比较两个文件夹:

  1. 仅比较名称并将仅存在于第一个文件夹中但不存在于第二个文件夹中的文件的名称写入文件夹 - 我一直在尝试 comp 并将文件名写入文本文件并使用 fc,但两者都显示我不需要的额外信息。我只需要已删除文件的名称。

  2. 比较两个文件夹中具有相同文件名的文件的大小,并列出与第一个文件夹相比,第二个文件夹中仅小 5% 以上的文件的列表。同样,我只需要这些文件的名称(如果可能,还需要百分比差异)。

我希望将两者的结果写入 txt 文件。

4

2 回答 2

1
@ECHO OFF
SETLOCAL
SET "dir1=."
SET "dir2=.\e"
SET "report1=u:\existinfirstnotsecond.txt"
SET "report2=u:\smallerinsecond.txt"
DEL "%report1%" 2>NUL >nul
DEL "%report2%" 2>NUL >nul
FOR /f "delims=" %%i IN ('dir /b /a-d "%dir1%\*"') DO (
 IF EXIST "%dir2%\%%i" (
  FOR %%q IN ("%dir1%\%%i") DO FOR %%s IN ("%dir2%\%%i") DO (
   CALL :sizes %%~zq %%~zs "%%i"
   )
 ) ELSE (
 >>"%report1%" ECHO %%i
 )
)

GOTO :EOF

:sizes
IF %2 GEQ %1 GOTO :EOF
IF %2 equ 0 SET "diff= LOTS"&GOTO report
SET /a diff=%1 - %2
SET /a diff=%diff%*10000/%1
IF %diff% LSS 500 GOTO :EOF
SET diff= %diff%
SET diff=%diff:~-4,2%.%diff:~-2%
:report
>>"%report2%" ECHO %diff%%% %~3
GOTO :eof

这应该会产生您想要的结果。您只需要替换 和 的dir1,dir2,report1设置report2

如果第一个文件名存在于第二个目录中,则将两者的大小和文件名发送到过程:sizes,否则,将在第二个目录中找到但丢失的文件的名称写入到report1

如果第一个的大小大于等于第二个的大小,不报,如果第二个文件的长度为0,那么%diff是无限的,否则计算差值,乘以10000除以结果由第一个文件的大小决定。结果是 0..10000;500表示5%,小于5%忽略不计,否则加前导空格,插入点,报差。

如果文件大于 200K,则可能会出现唯一的问题,其中数学需要更复杂一些(批处理仅限于 32 位有符号整数)


编辑 20130625-1958Z - For..%%i /%%q/%%s 循环替换原始循环以解决缺少目录名的问题。


编辑 20130626-1601Z -SIZES更长文件的替换例程

:sizes
:: establish the file sizes
SET siz1=%1&SET siz2=%2
:szloop
:: Size of file 1 insanely less than size of file 2 ?
IF NOT DEFINED siz1 GOTO :EOF 
:: Size of file 2 insanely less than size of file 1 ?
IF NOT DEFINED siz2 SET "diff= LOTS"&GOTO report
:: keep peeling the last digit from the sizes until
:: neither is more than 5 digits long
IF NOT %siz1:~5%%siz2:~5%x==x SET siz1=%siz1:~0,-1%&SET siz2=%siz2:~0,-1%&GOTO szloop
:: Now use SIZ1 and SIZ2
IF %siz2% GEQ %siz1% GOTO :EOF
IF %siz2% equ 0 SET "diff= LOTS"&GOTO report
SET /a diff=siz1 - siz2
SET /a diff=%diff%*10000/siz1
IF %diff% LSS 500 GOTO :EOF
SET diff= %diff%
SET diff=%diff:~-4,2%.%diff:~-2%
:report
>>"%report2%" ECHO %diff%%% %~3
GOTO :eof
于 2013-06-24T17:59:20.543 回答
1

OP的最终版本...

@ECHO OFF 

SETLOCAL

SET "dir1=P:\week3"
SET "dir2=P:\week4"

SET "report1=P:\Test\removed.txt"
SET "report2=P:\Test\existinfirstnotsecond.txt"
SET "report3=P:\Test\smallerinsecond.txt"
SET "report4=P:\Test\fullreport.txt" 

DEL "%report1%" 2>NUL >nul
DEL "%report2%" 2>NUL >nul
DEL "%report3%" 2>NUL >nul
DEL "%report4%" 2>NUL >nul

FOR /f "delims=" %%i IN ('dir /b /a-d "%dir2%\*"') DO (
IF NOT EXIST "%dir1%\%%i" (
    >> "%report1%" ECHO %%i
)
)

FOR /f "delims=" %%i IN ('dir /b /a-d "%dir1%\*"') DO (
IF EXIST "%dir2%\%%i" (
    FOR %%q IN ("%dir1%\%%i") DO (
        FOR %%s IN ("%dir2%\%%i") DO (
            CALL :sizes %%~zq %%~zs %%i
        )
    )
) ELSE (
    >> "%report2%" ECHO %%i
)
)

ECHO Old Folder is: %dir1% > "%report4%"
ECHO New Folder is: %dir2% >> "%report4%"
ECHO. >> "%report4%"
ECHO New files are: >> "%report4%"
TYPE "%report1%" >> "%report4%"
ECHO. >> "%report4%"
ECHO Removed files are: >> "%report4%"
TYPE "%report2%" >> "%report4%"
ECHO. >> "%report4%"
ECHO Files smaller by over 5%% are: >> "%report4%"
TYPE "%report3%" >> "%report4%"

START notepad "%report4%"

GOTO :EOF
::^^^^^:: This extra line inserted...PW

:sizes
SET siz1=%1
SET siz2=%2
SET name=%3

:simplify
IF [%siz1:~5%] NEQ [] (
IF [%siz2:~5%] NEQ [] (
    SET siz1=%siz1:~0,-1%
    SET siz2=%siz2:~0,-1%
    GOTO :simplify
)
)

SET /a diff=10000-(10000*%siz2%/%siz1%)

IF %diff% LSS 500 GOTO :EOF
SET diff=00%diff%
SET diff=%diff:~-4,2%.%diff:~-2% 

:report
>> "%report3%" ECHO %diff%%% %name%

GOTO :EOF

唯一需要的调整是按照指示添加额外的GOTO :EOF行,否则批处理的执行将直接传递到:sizes例程并可能呈现语法错误。

于 2013-06-27T15:42:30.157 回答