创建.bat文件以在字符串中的任何位置对具有类似模式的文件进

时间:2014-03-17 02:57:30

标签: java batch-file cmd

我卡住并且不确定如何进展,我想创建一个.bat文件,可以搜索目录(最终是子目录)并选择具有相似名称的文件,然后移动它们或将它们复制到基于该名称的新文件夹。

例如,我将这些文件放在文档目录中:

apples101.txt
101apples.txt
201applesohmy.doc
203apples101course.txt
101oranges.txt
orangesohmy101.txt
peeltheoranges.txt
orangejuice.txt

我希望将名称中带有“apple”的所有文件移动到名为Apple的文件夹中,并将名称中带有“Orange”的所有文件移动到名为orange的文件夹中。

关键是,搜索应该根据模式自动选择文件而不是我指定的内容。我的意思是,如果有一种方式,那么我不得不将苹果放入delim字符串,然后运行另一组带有橙色的命令,是否有一个我可以做的循环基本上搜索所有的文件和文件排序到他们自己的目录?

我知道我可以使用没有delim选项字符串的标记但是它不会搜索文件以匹配名称。

也许最好采取第一个文件名(不包括文件扩展名),或者说在名称中匹配6个字符,然后针对其余文件名运行文件名以查找模式匹配,然后移动这些文件进入一个名字相似的新文件夹?然后循环它以获取剩余的文件?

这可能吗?

在没有编译脚本的情况下,这可能是java吗?

1 个答案:

答案 0 :(得分:0)

这种类型的问题很难解决,因为涉及的规则数量很多。但是,我们可以开发一个"概念证明"程序,以测试它与真实数据的行为,然后尝试改进它引入新规则。

下面的批处理文件处理每个文件名,每次较小时将其划分为子字符串,计算与子字符串匹配的文件数,并在此数字大于1时立即停止,但仅当子字符串不启动时以数字结束。如前所述,这种方法可以通过引入新规则得到改进。

@echo off
setlocal EnableDelayedExpansion

set MAX_FILE_LEN=30
set DIGITS=0123456789

for /F "delims=" %%a in ('dir /B /A-D') do if exist "%%a" (
   set "fileName=%%~Na"
   for /L %%i in (1,1,%MAX_FILE_LEN%) do if "!fileName:~%%i,1!" neq "" set len=%%i
   ECHO/
   ECHO FILENAME="!FILENAME!", LEN=!LEN!
   set "baseName="
   for /L %%i in (!len!,-1,2) do if not defined baseName (
      set /A last=len-%%i+1
      for /L %%j in (0,1,!last!) do if not defined baseName (
         set "testName=!fileName:~%%j,%%i!"
         for /F "tokens=1,2" %%a in ("!testName:~0,1! !testName:~-1!") do (
            if "!DIGITS:%%a=!" equ "%DIGITS%" if "!DIGITS:%%b=!" equ "%DIGITS%" (
               for /F %%n in ('dir /B /A-D "*!testName!*.*" ^| find /V /C ""') do set num=%%n
               if !num! gtr 1 set "baseName=!testName!"
            )
         )
      )
   )
   if defined baseName (
      echo BaseName found: !baseName!, moving files:
      if not exist "!baseName!" md "!baseName!"
      move "*!baseName!*.*" "!baseName!"
   ) else (
      echo File name unique: !fileName!
      if not exist UniqueFiles md UniqueFiles
      move "*!baseName!*.*" UniqueFiles
   )
)

输出示例:

C:\test> dir /B
101apples.txt
101oranges.txt
201applesohmy.doc
203apples101course.txt
apples101.txt
orangejuice.txt
orangesohmy101.txt
peeltheoranges.txt

C:\test> ..\test

FILENAME="101apples", LEN=8
BaseName found: apples, moving files:
C:\test\101apples.txt
C:\test\201applesohmy.doc
C:\test\203apples101course.txt
C:\test\apples101.txt
Se han movido         4 archivos.

FILENAME="101oranges", LEN=9
BaseName found: oranges, moving files:
C:\test\101oranges.txt
C:\test\orangesohmy101.txt
C:\test\peeltheoranges.txt
Se han movido         3 archivos.

FILENAME="orangejuice", LEN=10
File name unique: orangejuice
C:\test\orangejuice.txt
Se han movido         1 archivos.

编辑添加新规则

此类解决方案取决于数据。这意味着一个完美的解决方案"对于特定数据不能保证获得,只是一个解决方案"比最后一个更好"如果可能的话。下面的解决方案引入了一个额外的规则:当匹配文件的数量增加时,它会获得连续的基本名称,但前提是前一个基本名称的长度只有一个字符不同。

@echo off
setlocal EnableDelayedExpansion

set MAX_FILE_LEN=30
set DIGITS=0123456789

for /F "delims=" %%a in ('dir /B /A-D') do if exist "%%a" (
   set "fileName=%%~Na"
   for /L %%i in (1,1,%MAX_FILE_LEN%) do if "!fileName:~%%i,1!" neq "" set len=%%i
   ECHO/
   ECHO FILENAME="!FILENAME!", LEN=!LEN!
   set "baseName="
   set "lastName="
   set /A lastNum=0, lastLen=0
   for /L %%i in (!len!,-1,2) do if not defined baseName (
      set /A last=len-%%i+1
      for /L %%j in (0,1,!last!) do if not defined baseName (
         set "testName=!fileName:~%%j,%%i!"
         for /F "tokens=1,2" %%a in ("!testName:~0,1! !testName:~-1!") do (
            if "!DIGITS:%%a=!" equ "%DIGITS%" if "!DIGITS:%%b=!" equ "%DIGITS%" (
               for /F %%n in ('dir /B /A-D "*!testName!*.*" ^| find /V /C ""') do set num=%%n
               if !num! gtr !lastNum! (
                  if !lastLen! equ 0 (
                     set "lastName=!testName!"
                     set /A lastNum=num, lastLen=%%i-1
                  ) else if %%i geq !lastLen! (
                     set "lastName=!testName!"
                     set /A lastNum=num, lastLen=%%i-1
                  ) else (
                     set "baseName=!lastName!"
                  )
               )
            )
         )
      )
   )
   if not defined baseName set "baseName=!lastName!"
   if !lastNum! gtr 1 (
      echo BaseName found: !baseName!, moving files:
      if not exist "!baseName!" md "!baseName!"
      move "*!baseName!*.*" "!baseName!"
   ) else (
      echo File name unique: !fileName!
      if not exist UniqueFiles md UniqueFiles
      move "*!baseName!*.*" UniqueFiles
   )
)