Windows批处理文件在树中查找重复项

Windows批处理文件在树中查找重复项,windows,batch-file,cmd,Windows,Batch File,Cmd,我需要一个批处理文件(Windows CMD是解释器,a.bat)来执行这类任务: 1) 搜索文件夹及其子文件夹 2) 查找具有相同文件名和扩展名的文件(也称为重复文件) 3) 检查它们是否有相同的尺寸 4) 如果名称相同+大小相同,则回显除第一个文件外的所有文件(实际上,我需要删除除一个副本外的所有文件) 谢谢你的帮助 这只是一个初始脚本,仅用于检查文件夹及其子文件夹中的文件及其大小: @Echo off Setlocal EnableDelayedExpansion Set Dir=C:\

我需要一个批处理文件(Windows CMD是解释器,a.bat)来执行这类任务:

1) 搜索文件夹及其子文件夹

2) 查找具有相同文件名和扩展名的文件(也称为重复文件)

3) 检查它们是否有相同的尺寸

4) 如果名称相同+大小相同,则回显除第一个文件外的所有文件(实际上,我需要删除除一个副本外的所有文件)

谢谢你的帮助

这只是一个初始脚本,仅用于检查文件夹及其子文件夹中的文件及其大小:

@Echo off
Setlocal EnableDelayedExpansion

Set Dir=C:\NewFolder

For /r "%Dir%" %%i in (*) do (
Set FileName=%%~nxi
Set FullPath=%%i
Set Size=%%~zi
Echo "!FullPath!" - SIZE: !Size!
)
Echo.
Pause

这个脚本可以满足您的要求。只需将顶部的根变量设置为指向树的根

@echo off
setlocal disableDelayedExpansion
set root="c:\test"
set "prevTest=none"
set "prevFile=none"
for /f "tokens=1-3 delims=:" %%A in (
  '"(for /r "%root%" %%F in (*) do @echo %%~znxF:%%~fF:)|sort"'
) do (
  set "currTest=%%A"
  set "currFile=%%B:%%C"
  setlocal enableDelayedExpansion
  if !currTest! equ !prevTest! echo "!currFile!"
  endlocal
  set "prevTest=%%A"
)
但是,通过使用FC比较文件的内容,可以使测试更加精确。此外,还可以将DEL命令直接合并到脚本中。下面的脚本打印出删除重复文件的命令。准备好实际删除文件时,请在DEL命令之前删除回显

@echo off
setlocal disableDelayedExpansion
set root="c:\test"

set "prevTest=none"
set "prevFile=none"
for /f "tokens=1-3 delims=:" %%A in (
  '"(for /r "%root%" %%F in (*) do @echo %%~znxF:%%~fF:)|sort"'
) do (
  set "currTest=%%A"
  set "currFile=%%B:%%C"
  setlocal enableDelayedExpansion
  set "match="
  if !currTest! equ !prevTest! fc /b "!prevFile!" "!currFile!" >nul && set match=1
  if defined match (
    echo del "!currFile!"
    endlocal
  ) else (
    endlocal
    set "prevTest=%%A"
    set "prevFile=%%B:%%C"
  )
)

这两组代码可能看起来过于复杂,但这只是因为我将代码结构化为健壮的代码,并避免了可能困扰简单解决方案的问题。例如,
可能会导致变量的问题,而文件名中的
=
会导致npocmoka的解决方案出现问题。

是否可以添加一些您尝试过的代码?另外,一些关于(例如)你的操作系统或命令解释器的信息对潜在的回答者来说是有用的。我写的代码在循环之后出现了一些问题,我不认为操作系统对.bat/CMD有什么影响,但WindowsXPtry正在考虑这个问题:我没有尝试过为Windows编写脚本/批处理文件,但在这种情况下,提问者似乎至少取得了一些成功。特别是,请看一下Win Vista之后提供的
for files
:for files/s/p/c“echo@relpath”将按相对路径列出所有文件,例如我有Xp,但没有for files,获取文件路径(如
for/R“MYDIR”%%i In(*)DO echo%%i
)但要检查副本、文件大小并比较所有信息+1,如果文件名包含
=
字符,则此操作将失败。但除此之外,它是一个很好且简单的算法。当你不使用它时,为什么会延迟扩展呢?如果名称包含
,则会导致问题。您的算法不需要延迟扩展。不,如果定义了,则不需要延迟扩展-这是我喜欢它的原因之一:-)您还有一个错误-您的变量名需要包含扩展名。您还有一个错误-您的变量名需要包含扩展名。最后一件事;-)您可能应该为每个变量名添加前缀,并清除所有以前缀开头的变量。您不希望由于任何已存在的变量而产生错误的结果。在Windows 10上,使用带有空格的根路径(例如set root=“c:\test path”)并在变量中加引号,我最终出现了此错误(注意前面没有引号,后面有两个双引号):此时未预料到路径“”。写的剧本是两次引用东西。解决方案是在定义变量时删除引号。要查找不一定具有相同文件名的重复项,您需要在此处删除哪些内容?所以我假设最快的方法是检查大小,并对大小相同的文件执行fc。
@echo off
setlocal disableDelayedExpansion
set root="c:\test"

set "prevTest=none"
set "prevFile=none"
for /f "tokens=1-3 delims=:" %%A in (
  '"(for /r "%root%" %%F in (*) do @echo %%~znxF:%%~fF:)|sort"'
) do (
  set "currTest=%%A"
  set "currFile=%%B:%%C"
  setlocal enableDelayedExpansion
  set "match="
  if !currTest! equ !prevTest! fc /b "!prevFile!" "!currFile!" >nul && set match=1
  if defined match (
    echo del "!currFile!"
    endlocal
  ) else (
    endlocal
    set "prevTest=%%A"
    set "prevFile=%%B:%%C"
  )
)