比较两个目录(每个目录都有多个子目录和文件夹)并在 Windows 中找到其中一个中不存在的文件

rdo*_*arn 2 windows file-management cmd.exe

我想比较两个独立驱动器中文件(例如图片)的两个目录(包括子文件夹)。我有数千个文件,并且隐藏在子目录和文件夹中。

小:示例

让我们在 C 中说:以下是文件夹和文件的列表

C:\folder1
          file01.jpeg
          file02.jpeg

C:\folder1\folder2 
          file10.jpeg

C:\folder1\folder2\folder3 
          file04.jpeg
          file05.jpeg

C:\folder1\folder4

          file06.jpeg
          file07.jpeg
          file03.jpeg
Run Code Online (Sandbox Code Playgroud)

D:具有相似的文件夹结构(可能不准确,除了文件夹 1 相同)但某些文件可能丢失或额外

D:\folder1
          file01.jpeg
          file08.jpeg

D:\folder1\folder2 
          file03.jpeg

D:\folder1\folder2\folder3 
          file04.jpeg

D:\folder1\folder4
          file06.jpeg
          file07.jpeg
          file09.jpeg
Run Code Online (Sandbox Code Playgroud)

现在我需要快速的方法(可能是 dos 命令行或软件,可以找到丢失或附加的文件并将文件放在新目录中,例如 D:\difference

D:\difference
    file02.jpeg 
    file05.jpeg
    file08.jpeg 
    file09.jpeg
    file10.jpeg     
Run Code Online (Sandbox Code Playgroud)

Kev*_*gan 5

移动文件的脚本如下...

如果您只想查看哪些文件相同/不同,可以使用windiff. 这可能有助于解决脚本问题。

所以,对于你的例子:

C:> windiff c:\folder1 d:\folder1
Run Code Online (Sandbox Code Playgroud)

Windiff 将打开并显示哪些文件是:

  • 完全相同的
  • 不同(表示哪个文件较新)
  • 仅左(文件仅存在于“第一个路径”(C:\folder1)中)
  • 仅右(文件仅存在于“第二个路径”(D:\folder1)中)

您可以使用命令行选项将结果保存到文件中-S::

-SS N:\path\filename.ext   [save list of identical files to filename.ext]
-SD N:\path\filename.ext   [save list of different files to filename.ext]
-SL N:\path\filename.ext   [save list of left-only files to filename.ext]
-SR N:\path\filename.ext   [save list of right-only files to filename.ext]
Run Code Online (Sandbox Code Playgroud)

此外,您可以在编写列表后包含Xwith-S来关闭windiff,如下所示:

-SRX N:\path\filename.ext   [save list of right-only files to filename.ext]
Run Code Online (Sandbox Code Playgroud)

您可以组合这些列表,因此如果您想要一个仅存在于(任何)一个路径中的文件列表:

C:> windiff -SLRX leftrightonly.txt c:\folder1 d:\folder1
Run Code Online (Sandbox Code Playgroud)

您一次只能生成一个“日志”文件,因此如果您想生成所有 4 个单独的“日志”文件,您必须运行 4 次 windiff:

C:> windiff -SSX same.txt c:\folder1 d:\folder1
C:> windiff -SDX different.txt c:\folder1 d:\folder1
C:> windiff -SLX leftonly.txt c:\folder1 d:\folder1
C:> windiff -SRX rightonly.txt c:\folder1 d:\folder1
Run Code Online (Sandbox Code Playgroud)

注意:存在于两个路径中但位于不同文件夹中的文件将显示为“leftonly”或“rightonly”。



如果您希望脚本将仅存在于一个路径中的文件移动到不同的文件夹,您可以使用下面的批处理脚本。

笔记:

  • 我将只存在于其中一个路径中的文件称为“孤独”文件。
  • 下面的脚本(带有变量"domove=0")将只显示“孤独”的文件而不移动它们。在测试脚本并确信将移动正确的文件后,您可以将值更改为:变量"domove=1"以显示和移动“孤独”文件。
  • 在脚本中,集sdrive1sdrive2sfolder,和sdifffolder必要的。
  • 或者,设置spath1, spath2,spathdiff如果这更适合您的使用。
  • 如果需要,可以轻松修改脚本以从命令行接受这些路径。

我做了以下假设:

  • 对于“第一个路径”中的每个文件,在整个“第二个路径”中搜索匹配的“filename.ext”。
  • 如果在“第二个路径”(单独文件)中未找到该文件,则会将其移动到“差异”文件夹中。
  • 不会尝试比较具有匹配文件名的文件,但可以轻松添加该功能。
  • 没有尝试考虑多个文件可能具有相同名称并位于“第一路径”的不同子文件夹中的可能性(“第二路径”相同)。如果发生这种情况的文件是“单独”文件,则这些文件中的每一个都将移动到“差异”文件夹,覆盖任何先前移动的同名文件。
  • 在“第二路径”中搜索“第一路径”中的每个文件后,向另一个方向重复该过程,对于“第二路径”中的每个文件,在整个“第一路径”中搜索匹配“文件名.ext”。

这是脚本:

@echo off

rem use "domove" for testing
rem if "%domove%" !=1, "lonely" files found will only be displayed (not moved).
rem if "%domove%"  =1, "lonely" files found will be displayed and moved.
set "domove=0"

set "sdrive1=C:\"
set "sdrive2=D:\"
set "sfolder=folder1"
set "sdifffolder=difference"

set "spath1=%sdrive1%%sfolder%"
set "spath2=%sdrive2%%sfolder%"
set "spathdiff=%sdrive2%%sdifffolder%"
rem spath1=C:\folder1, spath2=D:\folder1, spathdiff=D:\difference

rem ***************************************************

rem check if "path1" and "path2" exist
if exist "%spath1%" if exist "%spath2%" goto :check2
if not exist "%spath1%" echo Error: Path1:"%spath1%" does not exist.>&2
if not exist "%spath2%" echo Error: Path2:"%spath2%" does not exist.>&2
goto :EOF



:check2

    rem check if "path1" is empty (no files)
    dir /a-d /s /b "%spath1%">nul 2>&1
    if %errorlevel% EQU 0 goto :check3
    echo Error: Path1:"%spath1%" is empty (no files).>&2
    goto :EOF



:check3

    rem check if "path2" is empty (no files)
    dir /a-d /s /b "%spath2%">nul 2>&1
    if %errorlevel% EQU 0 goto :check4
    echo Error: Path2:"%spath2%" is empty (no files).>&2
    goto :EOF



:check4

    rem check if "%spathdiff%" exists, but is a file (error)
    if not exist "%spathdiff%" goto :start
    if exist "%spathdiff%\*" goto :start
    echo Error: Folder "%spathdiff%" conflicts with a file with the same name.>&2
    goto :EOF



:start

    rem get a list of all files in "first path", call :work1
    rem passing "(path1:)C:\path\...\filename.ext", "filename.ext", and "D:\path2"
    for /f "usebackq delims=" %%f in (`dir /s /b /a-d "%spath1%"`) do call :work1 "%%~f" "%%~nxf" "%spath2%"

    rem reverse the paths:
    rem get a list of all files in "second path", call :work1
    rem passing "(path2:)D:\path\...\filename.ext", "filename.ext", and "C:\path1"
    for /f "usebackq delims=" %%f in (`dir /s /b /a-d "%spath2%"`) do call :work1 "%%~f" "%%~nxf" "%spath1%"

    rem done, exit
    goto :EOF



:work1

    set "w1full=%~1"
    set "w1file=%~2"
    set "wpath2=%~3"

    rem "%w1file%" is the "target" "filename.ext" from "first path" to look for (in "second path").
    for /f "usebackq delims=" %%g in (`dir /s /b /a-d "%wpath2%"`) do call :work2 "%%~nxg" "%w1file%" "w1file"

    rem if "target" "filename.ext" from "first path" was found in the "second path",
    rem it is now empty. it means:
    rem file is somewhere in both paths... no action. go get next file from "first path"
    if "%w1file%."=="." goto :EOF

    rem at this point, "%w1file%" ("%w1full%") is a "lonely" file
    rem "%w1file%" only exists in "path1" move it to "difference" path
    rem additional checks might be necessary here
    rem to see if this file already exists in "difference" path
    if not exist "%spathdiff%" md "%spathdiff%">nul 2>&1
    echo Found "lonely" file %w1file%:   move "%w1full%" "%spathdiff%"
    if %domove% EQU 1 move /y "%w1full%" "%spathdiff%">nul 2>&1
    rem you can test %errorlevel% here for error: %errorlevel%=0 if no error

    rem go get next file from "first path"
    goto :EOF



:work2

    rem %1 is "current" "filename.ext" from "second path"
    rem %2 is "target" "filename.ext" from "first path"

    rem if "target" "filename.ext" is empty, return for more
    if "%~2."=="." goto :EOF

    rem if file from "first path" is found in "second path", 
    rem "clear" the variable holding the filename of the "target" "filename.ext" from "first path"
    rem additional checks might be necessary here
    rem to "compare" the two files
    if /I "%~1"=="%~2" set "%~3="
    goto :EOF
Run Code Online (Sandbox Code Playgroud)

这是使用您描述的示例文件集测试脚本的输出:

Found "lonely" file file02.jpeg:   move "c:\folder1\file02.jpeg" "d:\difference"
Found "lonely" file file10.jpeg:   move "c:\folder1\folder2\file10.jpeg" "d:\difference"
Found "lonely" file file05.jpeg:   move "c:\folder1\folder2\folder3\file05.jpeg" "d:\difference"
Found "lonely" file file08.jpeg:   move "d:\folder1\file08.jpeg" "d:\difference"
Found "lonely" file file09.jpeg:   move "d:\folder1\folder4\file09.jpeg" "d:\difference"
Run Code Online (Sandbox Code Playgroud)