【问题标题】:Group files from a directory to another directory with a particular pattern in filename将文件从一个目录分组到另一个目录,文件名中具有特定模式
【发布时间】:2019-01-14 21:27:56
【问题描述】:

所以我有一个目录 (D:\Project\Archive),其中包含许多具有不同文件名模式的 .txt 文件,扩展名之前的最后 9 个字符除外。 我以 6 个文件名为例:

  • 123456_HTQB_1412.txt
  • abcd_GGTL_7642.txt
  • 1a2b3_HTQB_1412.txt
  • 皮卡丘_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
    )

【问题讨论】:

  • 您必须在Goto :Eof 前面的一行中使用Goto :Eof 将被调用的子程序与正常程序流分开@

标签: windows batch-file cmd


【解决方案1】:

我建议采取不同的方法:

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

以下批次需要 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

【讨论】:

    猜你喜欢
    • 2020-06-03
    • 2017-07-20
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    相关资源
    最近更新 更多