使用文件名中的特定模式将文件从一个目录分组到另一个目录

时间:2019-01-14 21:27:57

标签: windows batch-file cmd

因此,我有一个目录(D:\ Project \ Archive),其中包含很多.txt文件,它们的文件名模式不同,但扩展名前的最后9个字符除外。 我列举了6个文件名作为示例:

  • 123456_HTQB_1412.txt
  • abcd_GGTL_7642.txt
  • 1a2b3_HTQB_1412.txt
  • pikachu_JTYU_7177.txt
  • hsbhsd_GGTL_7642.txt
  • yt7777_HTQB_7642.txt

这些文件没有特定的顺序。 显而易见的是,文件名的最后9个字符(在扩展名之前)遵循4个字符的模式,后跟一个下划线,后跟4个数字。这9个字符将在多个文件中相同。

我的目标是归档具有相同9个字符的文件,而不管文件数量如何。 zip文件的名称应为带有模式的9个字符,文件名应不包含这9个字符。上面的示例应创建3个存档文件:

  • HTQB_1412.zip-包含123456_.txt,1a2b3_.txt,yt7777_.txt。
  • GGTL_7642.zip-包含abcd_.txt,hsbhsd_.txt。
  • JTYU_7177.zip-包含pikachu_.txt。

我进行分组的方法是提取第一个文件名的模式,将文件移至_toArchive目录,然后循环浏览其余文件以检查相同的模式。如果匹配,则将其移动到目录_toArchive,并继续直到到达内部循环的末尾。然后,脚本将遍历到_toArchive,并压缩文件。然后控件返回到第一个循环以对其余文件重复相同的操作。

我面临的问题主要是分组问题。即使逻辑工作正常,但启用延迟扩展后,即使文件已移至其他目录,变量仍保留值。当循环尝试访问那些文件时,这会导致不必要的开销,从而导致“找不到文件”错误消息。有没有办法通过使用数组来取消设置变量?还是其他任何一种比我正在使用的方法都容易的方法?

我只是发布分组操作的代码,因为一旦弄清楚了,我将能够实现其余的代码。

set WORKDIR=D:\Project\Archive
setLocal enableDelayedExpansion
for /f "tokens=*" %%g in ('dir /b %WORKDIR%\*.txt') do (
    set firstFile=%%~ng
    set firstPattern=!firstFile:~-9!
    move /y %WORKDIR%\%%g %WORKDIR%\_toArchive
    call :checkPatterns
)
:checkPatterns
    for /f "tokens=*" %%i in ('dir /b %WORKDIR%\*.txt') do (
        set fileToGroup=%%i
        set groupedFile=%%~ni
        set groupedPattern=!groupedFile:~-9!
        call :groupPatterns
    )
:groupPatterns
    if "%groupedPattern%" == "%firstPattern%" (
        move /y %WORKDIR%\%fileToGroup% %WORKDIR%\_toArchive
    )

1 个答案:

答案 0 :(得分:0)

我建议采用其他方法:

  • 迭代所有文件并为每个组构建一​​个环境(数组)变量
  • 迭代组并将文件(具有短名称的文件)移动(或复制)到组-文件夹中
  • 将文件压缩到组文件夹中,然后删除该组文件夹

以下批次需要7zip才能在路径中的某个位置到达:

:: Q:\Test\2019\01\14\SO_54189436.cmd
@Echo off&SetLocal EnableDelayedExpansion

set WORKDIR=D:\Project\Archive

:: clear Group[] variables
for /f "delims==" %%A in ('Set Group[ 2^>Nul') Do set "%%A="

:: get groups
for /f "tokens=*" %%g in ('dir /b %WORKDIR%\*.txt') do (
    set FileName=%%~ng
    set "Group[!FileName:~-9!]=!FileName:~-9!"
)
set Group[
:: procss groups
for /f "tokens=2 delims==" %%A in ('Set Group[ 2^>Nul') Do (
  MD "%WORKDIR%\%%A" 1>Nul 2>&1
  for %%B in ("%WORKDIR%\*%%A.txt") Do Call :MoveRenFile "%%A" "%%B"
  Rem zip files and delete group folder
  PushD "%WORKDIR%\%%A"
  7z a "..\%%A.zip" *
  PopD
  RD /S /Q "%WORKDIR%\%%A" 
)

Goto :Eof
:MoveRenFile
Set "File=%~nx2"
set "NewName=%WORKDIR%\%~1\!File:_%~1=!"
Echo Move "%~2" "%NewName%"
     Move "%~2" "%NewName%" >NUL
Goto :Eof

文件被重命名并存储在组文件夹中的中间结果:

> tree %Workdir% /F
└───Project
    └───Archive
        ├───GGTL_7642
        │       abcd.txt
        │       hsbhsd.txt
        │
        ├───HTQB_1412
        │       123456.txt
        │       1a2b3.txt
        │
        ├───HTQB_7642
        │       yt7777.txt
        │
        └───JTYU_7177
                pikachu.txt

使用zip文件的最终结果:

> tree /F D:\
D:\
└───Project
    └───Archive
            GGTL_7642.zip
            HTQB_1412.zip
            HTQB_7642.zip
            JTYU_7177.zip