批处理脚本,用于检查目录中的重复文件

时间:2018-05-23 19:43:46

标签: file batch-file duplicates directory

尝试查看文件,例如

  

C:\ Users \ Admin \ Desktop \ Test \ 12345

     

C:\用户\管理员\桌面\测试\ 45635

     

C:\用户\管理员\桌面\测试\ 12345-2018-04-21

并创建一个名为“12345”的子文件夹,并将这两个文件(12345和12345-2018-04-21)存储在子文件夹“12345”中。这将遍历整个文件夹,以确保没有副本

:: ---------------------------------------------------------------
:: - This is a program that searches for files with the same 5 
::   digit number and puts them in a subfolder.
:: ---------------------------------------------------------------
@ECHO off

SETLOCAL
SET "sourcedir=C:\Users\Admin\Desktop\Test"
SET "destdir=C:\Users\Admin\Desktop\Test"
SET /a lastnum=200000

if "%first5%" equ "%lastnum%"(
SET "destdir=%destdir%\%first5%-sub"
 md %destdir%
)

FOR /f "delims=" %%a IN (
 'dir /b /a-d /on "%sourcedir%\*" '
 ) DO (
 CALL :detect "%%a"
 IF DEFINED dupnum (ECHO(MOVE "%sourcedir%\%%a" "%destdir%\")
)

GOTO end 

:: Routine to detect whether the first 5 characters of the filename "%1"
:: are all numeric and if so, whether they match the previous 5-digit number
:: found.

:detect
SET "dupnum="
:: Get the first 5 characters of the filename; prefix with a `1`
SET "fullfilename=%~1"
SET "first5=1%fullfilename:~0,5%"
IF "%first5%" neq "%lastnum%" (
 SET "lastnum=%first5%"
   GOTO end
)
:: First 5 chars of this filename = first 5 of previous filename
:: Check to see whether numeric
SET /a dummy=first5 + 0
IF "%dummy%" neq "%first5%" (
 SET "lastnum=%first5%"
   GOTO end 
)
SET "dupnum=Y"
   GOTO end 

ENDLOCAL

:end

PAUSE

不知道为什么我无法创建文件夹并将重复的文件存储到其中。它将通过我的测试文件夹读取并注意重复项并提示移动它们但我不确定我需要做什么才能将它移动到新文件夹。

1 个答案:

答案 0 :(得分:0)

如果您以前没有遇到过该语言,很难确定从哪里开始。

第一个问题是正确指定您的术语的含义。 A"重复文件"例如,通常意味着重复的内容或重复的名称(但由于目录只能容纳一个具有任何特定名称的文件,这意味着不同的目录)。在您的情况下,您的个人定义是"名称以相同的5位数开头的文件"。

由于这会导致使用许多技术的批处理(并且可能有许多方法),因此可以使用这个方法:

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET /a lastnum=200000

md %destdir% 2>nul

FOR /f "delims=" %%a IN (
 'dir /b /a-d /on "%sourcedir%\*" '
 ) DO (
 CALL :detect "%%a"
 IF DEFINED dupnum (ECHO(MOVE "%sourcedir%\%%a" "%destdir%\")
)

GOTO :EOF

:: Routine to detect whether the first 5 characters of the filename "%1"
:: are all numeric and if so, whether they match the previous 5-digit number
:: found.

:detect
SET "dupnum="
:: Get the first 5 characters of the filename; prefix with a `1`
SET "fullfilename=%~1"
SET "first5=1%fullfilename:~0,5%"
IF "%first5%" neq "%lastnum%" (
 SET "lastnum=%first5%"
 GOTO :eof
)
:: First 5 chars of this filename = first 5 of previous filename
:: Check to see whether numeric
SET /a dummy=first5 + 0
IF "%dummy%" neq "%first5%" (
 SET "lastnum=%first5%"
 GOTO :eof
)
SET "dupnum=Y"
GOTO :eof

您需要更改sourcedirdestdir的设置以适合您的具体情况。

为了测试目的,所需的MOVE命令仅为ECHO在您确认命令正确后,将ECHO(MOVE更改为MOVE以实际移动文件。附加>nul以取消报告消息(例如1 file moved

从根本上说,批处理代码不区分大小写,metavariable语句中for的明显例外(%%a以上)

批量对布局非常敏感,因此最好是剪切和粘贴而不是重新输入,并尝试重新格式化以配合一些更令人赏心悦目的风格。

通常假设批次代码是从提示中运行的,而不是通过“点击”。

语法SET "var=value"(其中value可以为空)用于确保任何杂散尾随空格不包含在分配的值中。 set /a通常可以使用"无报价"。

@echo off语句关闭命令回显,以便命令在执行之前回显到控制台。

setlocal语句会调用本地环境'以便在批次完成时处理对环境的任何改动或添加。

主循环首先执行dir命令以生成目录列表。选择的选项为/b - 基本(无页眉/页脚 - 仅限名称)/a-d - 无目录名和/on - 按名称排序(即按字母顺序排列)

dir命令的输出由for /f处理"delims="选项处理。这会将整个行分配给metavariable %%a

对于找到的每个文件名,执行子例程:detect。由于该rouine位于此批处理文件中,因此:语句中使用call。如果没有:,例程call ed将是名为detect的批处理文件(detect.batdetect.cmd,前者更受欢迎)

执行例程:detect后,可以设置或不设置名为dupnum的变量。如果已设置,echo字符串。如果没有,请不要。

例程:detect首先"将dupnum(例程的结果)设置为空字符串,如果存在,则从环境中删除该变量。

然后将变量fullfilename设置为从call语句传递的值。 %1表示"第一个参数"。 %~1表示"并删除封闭的引号"。引号是必需的,允许传递的文件名包含空格。

然后我们从完整文件名中获取前5个字符(来自"字符0和#34;对于5个字符),并以1为前缀。批处理将以0开头的字符串视为 octal 字符串(如果在数学运算中使用),因此1前缀可确保将现在的6个字符解释为十进制。 / p>

现在 - 如果first5不等于lastnum,那么我们会记录退出子例程的新lastnumgoto :eofdupnum尚未设置,因此调用循环不会显示此文件名。

接下来,如果前5个(好的,现在6个)字符都是数字,我们只想做移动。我们可以使用0在数学模式下将set /a添加到字符串中,这将导致相同的数字(如果这些字符是全数字的)或具有不同的数字(直到第一个非数字)如果" first5"包含非数字。

所以 - 测试结果 - 如果不同," first5"包含非数字,因此未设置dupnum的纾困。如果相同,则设置dupnum,以便报告文件名。

另请注意,官方备注说明为rem,但::(这是一个破损的标签 - 无法触及的标签)通常而是用于评论,因为它更容易打字并且对眼睛的侵扰性更小。但请注意::样式不能在code-block内使用(括号内分组的语句)

我添加了一个新行md ...,它应该创建目标目录。如果该目录已存在,2>nul将禁止错误消息。如果您希望此目录是源目录的子目录,那么请设置destdir

set "destdir=%sourcedir%\subdirectorynamedesired"