Batch file Windows批处理文件将1000个文件分组到字母数字文件夹中

Batch file Windows批处理文件将1000个文件分组到字母数字文件夹中,batch-file,Batch File,这是我在这里的第一个帖子/请求。我已经做了无数次搜索,试图找到一个解决方案,但我认为我的要求有点雄心勃勃 我使用的是Windows 7,我更喜欢在DOS批处理文件中执行此操作,而不是PowerShell 我的文件夹里有10万个旧的Zip档案。由于一个文件夹中有这么多文件,因此列出它们可能会很慢。我想将Zip档案移动到按字母顺序排列的文件夹中,但每个文件夹需要限制为1000个文件 因此,前1000个a*.zip文件将被移动到名为A1的文件夹中。第二个1000个a*.zip文件放入名为A2的文件夹中

这是我在这里的第一个帖子/请求。我已经做了无数次搜索,试图找到一个解决方案,但我认为我的要求有点雄心勃勃

我使用的是Windows 7,我更喜欢在DOS批处理文件中执行此操作,而不是PowerShell

我的文件夹里有10万个旧的Zip档案。由于一个文件夹中有这么多文件,因此列出它们可能会很慢。我想将Zip档案移动到按字母顺序排列的文件夹中,但每个文件夹需要限制为1000个文件

因此,前1000个a*.zip文件将被移动到名为A1的文件夹中。第二个1000个a*.zip文件放入名为A2的文件夹中,依此类推

文件需要按顺序移动,因此,如果复制到A1的最后一个文件是_example_file_97.zip,那么移动到A2文件夹的第一个文件将是_example_file_98.zip

我需要对整个字母表和数字命名的Zip存档文件执行此操作。然后我会得到这样的文件夹/文件结构

<DIR> 01
    1000 zip archives whose filename begins with a number
<DIR> 02
    Next 1000 zip archives whose filename begins with a number
<DIR> 03
    Next 1000 zip archives whose filename begins with a number

<DIR> A1
    1000 zip archives whose filename begins with A
<DIR> A2
    Next 1000 zip archives whose filename begins with A
<DIR> A3
    Next 1000 zip archives whose filename begins with A
<DIR> B1
    1000 zip archives whose filename begins with B
<DIR> B2
    Next 1000 zip archives whose filename begins with B
<DIR> B3
    Next 1000 zip archives whose filename begins with B

<DIR> Z1
    1000 zip archives whose filename begins with Z
<DIR> Z2
    Next 1000 zip archives whose filename begins with Z
<DIR> Z3
    Next 1000 zip archives whose filename begins with Z
01
1000个zip存档文件,其文件名以数字开头
02
下一个1000个zip归档文件,其文件名以数字开头
03
下一个1000个zip归档文件,其文件名以数字开头
A1
1000个zip存档文件,其文件名以
A2
下一个1000个zip归档文件,其文件名以
A3
下一个1000个zip归档文件,其文件名以
地下一层
1000个文件名以B开头的zip存档
地下二层
下一个1000个zip归档文件,其文件名以B开头
地下三层
下一个1000个zip归档文件,其文件名以B开头
Z1
文件名以Z开头的1000个zip存档
Z2
下一个1000个zip归档文件,其文件名以Z开头
Z3
下一个1000个zip归档文件,其文件名以Z开头
如果此网站上已经存在此解决方案,我深表歉意,但要确切知道要搜索什么是很困难的


谢谢。

在PowerShell中,我可能会采用以下方法(目前并不真正关心效率):

  • 获取文件列表:

    Get-ChildItem |
    
  • 按名称排序(名称中的数字按数字排序,而不是按字母排序)

    这将负责排序
    some-name-100
    之后的
    some-name-99

  • 按第一个字符分组:

    Group-Object {
      $first = $_.Name[0];
      # Emit only a 0 for all numbers
      if ($first -match '[0-9]') { '0' } else { $first }
    } |
    
  • 将这些组分成最多1000个元素的批次

    ForEach-Object {
      $name = $_.Name
      $group = $_.Group
      0..([Math]::Floor($_.Count / 1000)) |
        ForEach-Object {
          $items = $group[($_ * 1000)..($_ * 1000 + 999)
          [pscustomobject] @{
            FirstLetter = $name
            Index = $_ + 1
            Items = $items
          }
        }
    } |
    
  • 创建文件夹并将文件移动到各自的文件夹中

    ForEach-Object {
      $dir = New-Item Directory ($_.FirstLetter + $_.Index)
      $_.Items | Move-Item -Destination $dir
    }
    
  • 这是未经测试的,但可能或多或少会起作用。对于测试,您可能应该测试虚拟数据,并在
    移动项
    上包含
    -WhatIf


    所有这一切在
    cmd
    中都会比PowerShell痛苦得多,尤其是分组或数字排序。

    与Joey相反,我认为批量处理不会太复杂或痛苦

    数组中的计数需要在for循环中进行两级延迟扩展,但仅此而已

    @Echo off&SetLocal EnableExtensions EnableDelayedExpansion
    PushD "X:\start\here"
    for /F "Delims=" %%A in ('Dir /B /ON *') Do (
      Set "Name=%%~nA"
      Set "N=!Name:~0,1!"
      Echo !N!|Findstr "[0-9]" 2>&1>NUL &&Set N=0
      Set /A "Array[!N!]+=1"
      Call Set "Count=%%Array[!N!]%%"
      Set /A "F=!Count! / 1000 +1, I = !Count! %% 1000"
      Set "Dest=!N!!F!"
      If not Exist "!Dest!" REM MD "!Dest!"
      Echo Move "%%A" "!Dest!\"
    )
    Set Array[
    Pause
    Popd
    
    在重新调试MD命令时,
    仅回显移动命令

    查看counting Array[variable finally output]以查看将创建多少dir

    短路样本输出:

    Move "WSH_Shell_4.html" "W1\"
    Move "xyz" "x1\"
    Move "yarn.bat" "y1\"
    Move "ZehnerZaehlen.cmd" "Z1\"
    Move "zeiten.txt" "z1\"
    Array[0]=7
    Array[A]=10
    Array[B]=3
    Array[c]=30
    Array[D]=19
    Array[E]=15
    Array[F]=18
    Array[G]=29
    Array[H]=11
    Array[I]=9
    Array[J]=2
    Array[K]=1
    Array[L]=9
    Array[m]=20
    Array[N]=5
    Array[O]=4
    Array[P]=11
    Array[r]=16
    Array[S]=25
    Array[T]=17
    Array[U]=19
    Array[v]=3
    Array[W]=19
    Array[x]=1
    Array[y]=1
    Array[Z]=2
    
    @ECHO关闭
    SETLOCAL ENABLEDELAYEDEXPANSION
    设置“sourcedir=U:\sourcedir\t w o”
    设置“destdir=U:\destdir”
    设置“oldc1=*”
    设置“oldsd=*”
    设置“dircnt=4”
    对于/f“delims=”%%a IN(
    “%sourcedir%\*.zip”上的“dir/b/a-d/on”
    )做(
    设置“c1=%%a”
    设置“c1=!c1:~0,1!”
    如果/i“!c1!”neq“!oldc1!”(
    我们改变了最初的角色
    设置“oldc1=!c1!”
    设置“destsd=!c1!”
    对于(0 1 2 3 4 5 6 7 8 9)中的%%b,如果“%%b”==“!c1!”设置为“destsd=0”,则执行此操作
    如果/i“!oldsd!”neq“!destsd!”(
    设置/a fcount=dircnt-1
    设置/a olddestsd2=9
    设置“oldsd=!destsd!”
    )
    )
    设置/a fcount+=1
    SET/a destsd2=fcount/dircnt
    如果!destsd2!neq!olddestsd2(
    设置/a olddestsd2=destsd2
    ECHO MD“%destdir%\!destsd!!destsd2!”2>num
    )
    回显移动“%sourcedir%\%%a”“%destdir%\!destsd!!destsd2!\”
    )
    后藤:EOF
    
    您需要更改
    sourcedir
    的设置以适应您的环境

    您需要更改
    sourcedir
    destdir
    的设置以适应您的环境

    所需的MD命令仅用于测试目的。
    ECHO
    ed。验证命令正确后,将
    ECHO MD
    更改为
    MD
    ,以实际创建目录

    所需的移动命令仅用于测试目的。验证命令正确后,将
    ECHO MOVE
    更改为
    MOVE
    ,以实际移动文件。追加
    >nul
    以抑制报告消息(例如
    1个文件移动

    将帖子剪切并粘贴到.BAT文件中。不要因为感觉上的原因而尝试重新格式化—批处理对布局非常敏感

    为了进行测试,我将值
    dircnt
    设置为4。您的应用程序需要1000

    我建议您使用一些虚拟目录进行测试

    此例程使用
    延迟扩展
    ,其中
    %var%
    表示解析
    代码块
    (带括号的语句组)时变量的值,
    !var!
    表示循环中可能更改的值

    第一个问题是在内存中生成一个目录列表,该列表按字母顺序(
    /on
    )和基本格式(
    /b
    )[仅名称]排序,没有目录名(
    /a-d
    )。然后,
    for
    命令读取每一行,并分配给
    %a

    然后使用
    c1
    来包含文件名的第一个字符,该字符与
    oldc1
    的前一个值进行比较,以便仅当文件名的第一个字符更改时才重新计算目标目录名

    如果文件名的第一个字符为数字,则目标子目录为wi
    Move "WSH_Shell_4.html" "W1\"
    Move "xyz" "x1\"
    Move "yarn.bat" "y1\"
    Move "ZehnerZaehlen.cmd" "Z1\"
    Move "zeiten.txt" "z1\"
    Array[0]=7
    Array[A]=10
    Array[B]=3
    Array[c]=30
    Array[D]=19
    Array[E]=15
    Array[F]=18
    Array[G]=29
    Array[H]=11
    Array[I]=9
    Array[J]=2
    Array[K]=1
    Array[L]=9
    Array[m]=20
    Array[N]=5
    Array[O]=4
    Array[P]=11
    Array[r]=16
    Array[S]=25
    Array[T]=17
    Array[U]=19
    Array[v]=3
    Array[W]=19
    Array[x]=1
    Array[y]=1
    Array[Z]=2
    
    @Echo off
    SetLocal EnableExtensions EnableDelayedExpansion
    
    PushD "X:\start\here"
    for %%A in (*.*) Do (
       Set "Name=%%~nA"
       Set "N=!Name:~0,1!"
       If "!N!" lss "a" Set "N=0"
       Set /A "Array[!N!]+=1, F=Array[!N!] / 1000 +1"
       Set "Dest=!N!!F!"
       If not Exist "!Dest!" REM MD "!Dest!"
       Echo Move "%%A" "!Dest!\"
    )
    
    for %%L in (0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) Do (
       for /F "Delims=" %%A in ('Dir /B /ON %%L*') Do (