windows 比较两个文件夹及其子文件夹批处理文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17599576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing Two Folders and its Subfolder batch file
提问by user2296207
I have two folders that contain all the same files and subfolders, but the conents inside each file may have changed. I want to write a batch file that will search through each file and look for any differences. What's the best tool for what I want to do?
我有两个文件夹,其中包含所有相同的文件和子文件夹,但每个文件中的内容可能已更改。我想编写一个批处理文件来搜索每个文件并查找任何差异。什么是我想做的最好的工具?
回答by dbenham
No need for a batch file. A single FC command can do what you want:
不需要批处理文件。单个 FC 命令可以执行您想要的操作:
fc folder1\* folder2\*
You can be more specific for the file mask in the first folder if you want. For example folder1\*.txt
.
如果需要,您可以更具体地指定第一个文件夹中的文件掩码。例如folder1\*.txt
。
The command will report on files that exist in folder1 but are missing in folder2. Extra files in folder2 are simply ignored.
该命令将报告文件夹 1 中存在但文件夹 2 中缺失的文件。folder2 中的额外文件会被忽略。
There are a number of options to the FC command. Enter HELP FC
or FC /?
from the command prompt to get more information.
FC 命令有许多选项。在命令提示符下输入HELP FC
或FC /?
以获取更多信息。
EDIT
编辑
Extending the solution to support subfolders is a bit tricky. It is easy to iterate the folder hierarchy for a given root using FOR /R. The problem is getting the relative paths so that the hierarchy can be applied to another root.
扩展解决方案以支持子文件夹有点棘手。使用 FOR /R 迭代给定根目录的文件夹层次结构很容易。问题是获取相对路径,以便可以将层次结构应用于另一个根。
The simplest solution is to use FORFILES instead, since it directly supports relative paths. but FORFILES is... S L O W :/
最简单的解决方案是改用 FORFILES,因为它直接支持相对路径。但 FORFILES 是......慢:/
At this point, a batch file makes sense:
此时,批处理文件是有意义的:
@echo off
setlocal
set "folder1=c:\path\To\Folder1\Root"
set "folder2=d:\path\To\Folder2\Root"
set "fileMask=*"
for /f "delims=" %%F in (
'echo "."^&forfiles /s /p "%folder1%" /m "%fileMask%" /c "cmd /c if @isdir==TRUE echo @relpath"'
) do fc "%folder1%\%%~F\%fileMask%" "%folder2%\%%~F\*"
回答by Gregory D. Mellott
I'm having better luck with the following batch file. The path names have to completely match though; so only the Drive Letter differs.
我对以下批处理文件的运气更好。路径名必须完全匹配;所以只有驱动器号不同。
Mapping a shared network folder may make this easier. I can't say for sure for your case.
映射共享网络文件夹可能会使这更容易。我不能肯定你的情况。
'--- setlocal set "folder1=D:\User\Public" set "Drv2=E:" set "fileMask=*"
'--- setlocal set "folder1=D:\User\Public" set "Drv2=E:" set "fileMask=*"
setlocal
set "folder1=<DrvLttr>:\<Folder>\<SubFolder>"
set "Drv2=<DrvLttr2>:"
set "LogFile=<SystemDrv>\User\<UserName>\<LogFileName>"
ECHO "the '>' may OVER WRITE or make a ~NEW~ File for the results" > "%LogFile%"
ECHO " '>>' adds to the end of the file >> "%LogFile%"
FOR /R %folder1% %%A in ( *.* ) DO FC "%%A" "%Drv2%%%~pnxA" 1>> "%LogFile%" 2>&1
If you wish to note what is going to be the command for testing, you can try inserting ECHO after DO. You can drop the 1>>... stuff to see the result on screen, instead of having to open the output file.
如果您想注意将要执行的测试命令,您可以尝试在 DO 之后插入 ECHO。您可以删除 1>>... 内容以在屏幕上查看结果,而不必打开输出文件。
回答by David
I modified a batch file I wrote for a CD process that should meet your need. It
我修改了我为应该满足您需要的 CD 进程编写的批处理文件。它
- takes 2 directory trees and compares each file in each tree
- creates a list of the file differences (named File_differences.txt in the output folder)
- and creates a folder with a diff file for each non-matching object
- 采用 2 个目录树并比较每个树中的每个文件
- 创建文件差异列表(在输出文件夹中命名为 File_differences.txt)
- 并为每个不匹配的对象创建一个带有 diff 文件的文件夹
If both directory structures are under the same parent, then all you need to do is update the first 8 variables in the script. If the directory trees have different parents, then read through the scripts comments. Particularly lines 14, 38 and 46.
如果两个目录结构都在同一个父目录下,那么您需要做的就是更新脚本中的前 8 个变量。如果目录树有不同的父目录,则通读脚本注释。特别是第 14、38 和 46 行。
:: This script compares the contents of 2 trees
:: set a workspace location for the script outside of the trees being reviewed
set home=D:\path\to\batch_file_home
set Input=D:\path\to\batch_file_home\Input_Files
set Resource=D:\path\to\batch_file_home\Resource_Files
set Output=D:\path\to\where your want to view your\Output_Files
set environment=D:\path\to\parent directory containing the different tree structures (if they do not share a parent, then make this the drive)
:: the next 3 lines are only needed if you want to predefine multiple directories for comparison
set Prod=production
set QA=test
set Dev=branches\dev
:: If you remove the 3 lines above, then you need to replace the 2 below variables with values
:: If the trees are not under the same parent, then include the full path for Tree A and B below
set Tree_A=%Prod%
set Tree_B=%QA%
:: if you already have an object list, place it in the Input folder and remove lines 24 through 35 of this script
set Object_List=Object_List_minus_Direcotries.txt
set Output_File=File_differences.txt
if exist %Output%\%Output_File% del %Output%\%Output_File%
if exist %Output%\Differences\*.txt del %Output%\Differences\*.txt
if exist %Resource%\* del /q %Resource%\*
:: since you state the objects in both trees are always the same, I have not included a comparison to verify the 2 trees match
:: this section identifies the contents of Tree A
cd %environment%\%Tree_A%
dir /b /s > %Resource%\Complete_Tree_A_Object_List.txt
:: Next, remove the objects that are directories
setlocal enabledelayedexpansion
for /f "tokens=*" %%p in (%Resource%\Complete_Tree_A_Object_List.txt) do (
dir /a:d /b %%p 2>nul >nul && (set object_type=folder) || (set object_type=file)
echo !object_type!
if !object_type!==file echo %%p >> %Resource%\%Object_List%
)
:: in the object list, remove the parent tree from the path
:: if the Trees are not under the same parent, then comment out the below 6 lines
powershell -command "(Get-Content %Resource%\%Object_List%) -replace '\','/' | set-content %Resource%\%Object_List%"
powershell -command "(get-content %Resource%\%Object_List%) | Foreach {$_.TrimEnd()} | Set-Content %Resource%\%Object_List%"
set remove_parent_prefix=%environment%\%Tree_A%
set remove_parent_prefix=%remove_parent_prefix:\=/%
powershell -command "(Get-Content %Resource%\%Object_List%) -replace '%remove_parent_prefix%/','' | set-content %Resource%\%Object_List%"
powershell -command "(Get-Content %Resource%\%Object_List%) -replace '/','\' | set-content %Resource%\%Object_List%"
:: the below loop assumes both Trees are under the same parent. If this is not the case, replace the cd %environment% line with cd %home%
:: when the Trees are not under the same parent, set home to the root location, example cd D:\
setlocal enabledelayedexpansion
for /f "tokens=*" %%x in (%Resource%\%Object_List%) do (
set Diff_File=%%x
set Diff_File=!Diff_File:\=-!
cd %environment%
fc %Tree_A%\%%x %Tree_B%\%%x > "%Output%\Differences\!Diff_File!-%Output_File%"
for %%a in ("%Output%\Differences\!Diff_File!-%Output_File%") do for /f %%b in ('find /c /v "" ^< "%%a" ') do if %%b LSS 3 del "%%a"
for %%R in ("%Output%\Differences\!Diff_File!-%Output_File%") do if not %%~zR lss 1 (
echo %%x >> %Output%\%Output_File%
)
for %%R in ("%Output%\Differences\!Diff_File!-%Output_File%") do if %%~zR lss 1 (
del "%Output%\Differences\!Diff_File!-%Output_File%"
)
)
endlocal
:: Clean up Resources. If you want to review the temp files used to create the report, comment out the below line
if exist %Resource%\* del /q %Resource%\*
回答by Safwan
Here is another way to accomplish the task. Set the variables Folder1and Folder2to the full path of the folders you want to compare and run the batch file.
这是完成任务的另一种方法。将变量Folder1和Folder2设置为要比较并运行批处理文件的文件夹的完整路径。
Output:
输出:
Dup– the file exists in both folders and are identical.
Dup– 该文件存在于两个文件夹中并且是相同的。
Dif- the file exists in both folders but the content of the files are different.
Dif- 该文件存在于两个文件夹中,但文件的内容不同。
New– The file exists in one folder but not the other.
新建– 文件存在于一个文件夹中,但不存在于另一个文件夹中。
@Echo Off
SetLocal EnableDelayedExpansion
Set "Folder1=%UserProfile%\Desktop\Test Folder1"
Set "Folder2=%UserProfile%\Desktop\Test Folder2"
For /R "%Folder1%" %%x In (*.*) Do (
Set "FullPath=%%x"
Set "RelPath=!FullPath:%Folder1%=!"
If Exist "%Folder2%!RelPath!" (
>Nul 2>&1 FC /b "%Folder1%!RelPath!" "%Folder2%!RelPath!" && (
Echo Dup - %%x
)||(
Echo Dif - %%x
)
) Else (
Echo New - %%x
)
)
For /R "%Folder2%" %%x In (*.*) Do (
Set "FullPath=%%x"
Set "RelPath=!FullPath:%Folder2%=!"
If Not Exist "%Folder1%!RelPath!" (
Echo New - %%x
)
)