Board logo

标题: [文件操作] 【已解决】批处理如何通过文件名排序按20个文件作为一组转移归类到新的文件夹中 [打印本页]

作者: 翘翘猪    时间: 2024-8-2 11:32     标题: 【已解决】批处理如何通过文件名排序按20个文件作为一组转移归类到新的文件夹中

一:需求背景:
1.1、D:\sql路径下,有上千个以sql为后缀的文件,我期望把这些sql文件,按文件名以A-Z的顺序排序,转移归类到D:\sql_groups文件夹路径下面新的文件夹中:
1.2、比如第一次转移20个文件作为一组,将这20个文件转移到新的文件夹,并命名1-20
1.3、然后第二次转移剩余的文件,也是20个文件作为一组,将这20个文件转移到新的文件夹,并命名21-40
1.4、接着第三次转移剩余的文件,也是20个文件作为一组,将这20个文件转移到新的文件夹,并命名31-50
..........
1.5、直到遍历D:\sql路径下的所有文件全部转移到新的文件夹为止。

二:最后结果是:
2.1、D:\sql文件夹为空
2.2、D:\sql_groups文件夹路径下面有很多(1-20、21-40、41-60、61-80.....这样的文件夹)

三:发帖前的工作
3.1、有通过关键字搜过论坛中的相关帖子,没有找到相关的内容
3.2、有问过百度AI和讯飞星火,得出的脚本均无法执行

四:其中百度AI的bat脚本如下(运行报错:找不到文件,同时还把我D:\sql文件夹删掉了,幸好我提前备份):
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "sourceDir=D:\sql"
  4. set "destDir=D:\sql_groups"
  5. set /a "groupSize=20"
  6. set /a "groupNum=1"
  7. set /a "fileCount=0"
  8. if not exist "%destDir%" mkdir "%destDir%"
  9. for /f "delims=" %%f in ('dir /b /o-n "%sourceDir%*.sql"') do (
  10.     set /a "fileCount+=1"
  11.     set /a "groupEnd=!((fileCount-1) / %groupSize% + 1) * %groupSize%!"
  12.     set "folderName=%destDir%\!groupNum!-!groupEnd!"
  13.    
  14.     if not exist "!folderName!" mkdir "!folderName!"
  15.    
  16.     move "%sourceDir%\%%f" "!folderName!\"
  17.    
  18.     if !fileCount! equ !groupEnd! (
  19.         set /a "groupNum+=1"
  20.     )
  21. )
  22. :: 清理空的源文件夹(可选)
  23. rd /s /q "%sourceDir%"
  24. echo.
  25. echo All files have been grouped and moved to folders.
  26. pause
复制代码
五:百度AI针对这段脚本的说明如下
5.1、这个脚本会按文件名从Z到A的顺序排序文件(因为dir /b /o-n命令默认按名称降序排序)。如果你需要按A到Z的顺序,只需去掉/o-n选项,因为dir /b默认就是按名称升序排序的。

5.2、脚本中groupEnd的计算方式是确定当前文件应该属于哪个组的结束编号。它通过将当前文件计数(减1)除以组大小,然后加1并乘以组大小来得到。这样,当文件计数是组大小的倍数时,groupEnd会恰好是下一个组的起始编号减1,但由于我们总是创建到groupEnd的文件夹(包括它本身),所以实际上这不会影响分组的结果。

5.3、脚本最后有一个可选的命令来清理空的源文件夹。这个命令是rd /s /q "%sourceDir%",它会删除%sourceDir%及其所有子目录和文件,且不会提示确认。请确保在运行此命令之前,你已经将所有需要的文件都移动到了新位置,并且这个源文件夹不再需要。如果你不想自动删除源文件夹,请注释掉或删除这一行。

5.4、请注意,如果D:\sql下有非.sql文件,它们将不会被处理。如果你还想处理其他类型的文件,可以调整dir /b /o-n "%sourceDir%*.sql"命令中的文件扩展名部分。

5.5、脚本中的pause命令用于在脚本执行完毕后暂停窗口,以便你可以查看任何可能的错误消息或确认结果。在生产环境中,你可能希望去掉这个命令或将其替换为日志记录功能。
作者: qixiaobin0715    时间: 2024-8-2 11:46

本帖最后由 qixiaobin0715 于 2024-8-2 11:48 编辑
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%i in ('dir /b /a-d *.sql') do (
  4.     set /a n+=1
  5.     set /a x=n%%20
  6.     if !x! equ 1 (
  7.         set /a m=n+20-1
  8.         set "Folder=sql_groups\!n!-!m!"
  9.         md "!Folder!"
  10.     )
  11.     move "%%i" "!Folder!\"
  12. )
  13. pause
复制代码

作者: 翘翘猪    时间: 2024-8-2 12:02

大神好牛叉!已经可以实现,抓取sql文件分组条件好像并没有按A-Z来呢,还可以优化下吗?回复 2# qixiaobin0715
作者: qixiaobin0715    时间: 2024-8-2 12:05

回复 3# 翘翘猪
不知你的文件名是什么样式?
作者: 翘翘猪    时间: 2024-8-2 14:01

回复 4# qixiaobin0715

文件名由:字母+点+下划线+中杠+数字组成
我用下面这个直观的文件名来手动模拟(共计95个文件):
dbo.bathome_bbs_user_sp - Copy (1).sql
dbo.bathome_bbs_user_sp - Copy (2).sql
dbo.bathome_bbs_user_sp - Copy (3).sql
dbo.bathome_bbs_user_sp - Copy (4).sql
dbo.bathome_bbs_user_sp - Copy (5).sql
dbo.bathome_bbs_user_sp - Copy (6).sql
dbo.bathome_bbs_user_sp - Copy (7).sql
dbo.bathome_bbs_user_sp - Copy (8).sql
dbo.bathome_bbs_user_sp - Copy (9).sql
dbo.bathome_bbs_user_sp - Copy (10).sql
........
dbo.bathome_bbs_user_sp - Copy (95).sql

并不是按文件夹-->名称-->排序-进行排序
1-20文件夹是:
dbo.bathome_bbs_user_sp - Copy (1).sql
dbo.bathome_bbs_user_sp - Copy (2).sql
dbo.bathome_bbs_user_sp - Copy (10).sql~dbo.bathome_bbs_user_sp - Copy (27).sql----->连续文件共计18个


21-40文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (3).sql
dbo.bathome_bbs_user_sp - Copy (4).sql
dbo.bathome_bbs_user_sp - Copy (28).sql~dbo.bathome_bbs_user_sp - Copy (48).sql----->连续文件共计18个


41-60文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (5).sql
dbo.bathome_bbs_user_sp - Copy (6).sql
dbo.bathome_bbs_user_sp - Copy (46).sql~dbo.bathome_bbs_user_sp - Copy (63).sql----->连续文件共计18个


61-80文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (7).sql
dbo.bathome_bbs_user_sp - Copy (8).sql
dbo.bathome_bbs_user_sp - Copy (64).sql~dbo.bathome_bbs_user_sp - Copy (81).sql----->连续文件共计18个


81-100文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (9).sql
dbo.bathome_bbs_user_sp - Copy (82).sql~dbo.bathome_bbs_user_sp - Copy (95).sql----->连续文件共计14个


-----------------------------------------------------------
Bin哥大神
1、最后一组,如果文件只有95个,那么就标记是95,如果这个不好弄,没有关系,主要需求是排序归类存放

2、这两个文件夹路径可以通过变量来赋值吗?比如百度AI这样(使用的时候,方便灵活一点)
set "sourceDir=D:\sql"
set "destDir=D:\sql_groups"

3、后缀可以多个吗?比如我既要.sql又要.txt(方便以后如果有其它衍生需求,能用得上)

我的期望是D:\sql_groups下面的文件夹归类sql文件如下:

1-20文件夹内的文件是:

dbo.bathome_bbs_user_sp - Copy (1).sql~dbo.bathome_bbs_user_sp - Copy (20).sql

21-40文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (21).sql~dbo.bathome_bbs_user_sp - Copy (40).sql

41-60文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (41).sql~dbo.bathome_bbs_user_sp - Copy (60).sql

61-80文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (61).sql~dbo.bathome_bbs_user_sp - Copy (80).sql

81-95文件夹内的文件是:
dbo.bathome_bbs_user_sp - Copy (81).sql~dbo.bathome_bbs_user_sp - Copy (95).sql
作者: 翘翘猪    时间: 2024-8-2 14:06

回复 4# qixiaobin0715
实际情况,没有我上一楼回复您这么规则的文件名,我是为了方便演示,给大神手动模拟的。文件名都是:以字母+点+下划线+中杠+数字(大部分没有数字)组成
作者: qixiaobin0715    时间: 2024-8-2 14:30

回复 6# 翘翘猪
你在顶楼说是按A-Z的顺序(我的理解是按字母顺序)来移动文件,看你现在例子,是按括号中数字大小顺序。
作者: qixiaobin0715    时间: 2024-8-2 14:49

你可以在文件夹中运行下面这行代码,把得到的out.txt文件发到网盘里,让大家看看你要处理的文件到底是什么样的:
  1. dir /b /a-d>out.txt
复制代码

作者: 翘翘猪    时间: 2024-8-2 14:52

回复 7# qixiaobin0715
实际使用情况,没有我回复您这么规则的文件名,我是为了方便演示,给大神手动模拟的,正常文件名都是:以字母+点+下划线+中杠+数字(大部分没有数字),更是没有括号,因为是数据库存储过程,不存在这种不规则的命名方式。

我是为了演示多个文件,然后复制+粘贴 才出现这个括号,大神您已经帮到我忙了,我在生产环境中操作,已经可以按顺序排序归档,但是否100%按顺序,我也没办法区分,因为上千个sql文件,但我大致瞟几眼,全部都是按A-Z排序的。
下面3个要求,能帮忙追答吗?

1、可以不用删除原来的文件吗?即归类到新的文件夹后,原来的D:\sql文件夹的文件还保留不动。

2、这两个文件夹路径可以通过变量来赋值吗?比如百度AI这样(使用的时候,方便灵活一点)
set "sourceDir=D:\sql"
set "destDir=D:\sql_groups"

3、后缀可以多个吗?比如我既要.sql又要.txt(方便以后如果有其它衍生需求,能用得上)

再次感谢大神!
作者: 翘翘猪    时间: 2024-8-2 14:59

你可以在文件夹中运行下面这行代码,把得到的out.txt文件发到网盘里,让大家看看你要处理的文件到底是什么样 ...
qixiaobin0715 发表于 2024-8-2 14:49
  1. dir /b /a-d>out.txt
复制代码
得到的是我用您的脚本执行后,归类文件一样的排序,这个已经OK了,是我的模拟数据与实际的数据有偏差导致,您已经帮我按系统默认的顺序排序了,符合我的要求。
作者: qixiaobin0715    时间: 2024-8-2 15:04

本帖最后由 qixiaobin0715 于 2024-8-6 10:23 编辑

代码未测试,看看是不是这样:
  1. @echo off
  2. set "sourceDir=D:\sql"
  3. set "destDir=D:\sql_groups"
  4. set "Extensions=sql txt"
  5. set GNum=20
  6. cd /d "%sourceDir%"
  7. setlocal enabledelayedexpansion
  8. for /f "delims=" %%i in ('dir /b /a-d^|findstr /e "%Extensions%"') do (
  9.     set /a n+=1
  10.     set /a m=n%%GNum
  11.     if !m! equ 1 (
  12.         set /a x=n
  13.         set /a y=x+GNum-1
  14.         set "Folder=%destDir%\!x!-!y!"
  15.         md "!Folder!"
  16.     )
  17.     copy "%%i" "!Folder!\"
  18. )
  19. if !n! neq !y! ren "!Folder!" "!x!-!n!"
  20. pause
复制代码

作者: 翘翘猪    时间: 2024-8-2 15:19

代码未测试,看看是不是这样:
qixiaobin0715 发表于 2024-8-2 15:04

太牛逼了,完美解决了我的所有问题,感谢大神!以下是上面追加的问题,全部解决,我把标题改下。

1、可以不用删除原来的文件吗?即归类到新的文件夹后,原来的D:\sql文件夹的文件还保留不动。--OK

2、这两个文件夹路径可以通过变量来赋值吗?比如百度AI这样(使用的时候,方便灵活一点)--OK
set "sourceDir=D:\sql"
set "destDir=D:\sql_groups"

3、后缀可以多个吗?比如我既要.sql又要.txt(方便以后如果有其它衍生需求,能用得上)--OK
作者: qixiaobin0715    时间: 2024-8-2 15:32

回复 12# 翘翘猪
11楼代码已修改,满足“最后一组,如果文件只有95个,那么就标记是95”。
作者: 翘翘猪    时间: 2024-8-2 16:34

回复  翘翘猪
11楼代码已修改,满足“最后一组,如果文件只有95个,那么就标记是95”。
qixiaobin0715 发表于 2024-8-2 15:32

好的,大神,我看到了,当时我还觉得非常奇怪,我第一次复制的代码,怎么少几行,后面再次去复制的代码多了几行,后面经过比对,才发现你是帮我再默默的改了:最后一组,如果文件只有95个,那么就标记是95。




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2