[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文件操作] [已解决]批处理如何将文件按照特定规则放入不同的文件夹分组?

本帖最后由 bataiping 于 2020-12-26 11:45 编辑

情况是这样的:
举例我有一个“2014”文件夹,里面有n个pdf文件,每个大小不等
我想自动把这个pdf文件自动复制到“2014-1”“2014-2”...(自动生成)等文件夹中,每个文件夹中的文件总大小不大于500MB。
当然,这个排序要按照次序来,举例:
0001.pdf 10m
0002.pdf 480m
0003.pdf 50m
0004.pdf 10m
0005.pdf 300m
0006.pdf 200m
0007.pdf 100m
0008.pdf 400m
...
这种情况下,0001和0002放入“2014-1”,0003-0005放入“2014-2”,0006和0007放入“2014-3”,最后一个放入“2014-4”这样,所有的文件夹大小都不大于500m,且顺序不乱。

大佬请问这个怎么实现?

比如0003、0004、0005虽然加在一起只有360M,但是顺序不能乱,所以不能跳过0006把0007加进来。

TOP

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /a maxSize = 500 * 1024 * 1024, n = 1, size = 0
  4. for /f "delims=" %%i in ('dir /b *.txt') do (
  5.     set /a size += %%~zi
  6.     if !size! GTR !maxSize! (
  7.         set /a n += 1, size = %%~zi
  8.     )
  9.     md 2014-!n! 2>nul
  10.     move "%%i" 2014-!n!\
  11. )
  12. pause
复制代码
1

评分人数

TOP

回复 3# WHY


    w老师,可以麻烦您看一下私信吗?想请教您一些问题

TOP

回复 3# WHY

谢谢老师,我在此基础上稍微修改了一点,但是还是有两个需求不知道怎么改

::问题1:自身就超过限制大小的PDF文件会自己占一个文件夹,能否加个提示写入日志
::问题2:编号能否等宽统一3位
  1. @echo off
  2. for /f "delims=" %%i in ("%cd%") do set wjj=%%~ni
  3. setlocal enabledelayedexpansion
  4. set /p val=请输入大小限制(单位MB):
  5. set /a maxSize = %val% * 1024 * 1024, n = 1, size = 0
  6. for /f "delims=" %%i in ('dir /b *.pdf') do (
  7.     set /a size += %%~zi
  8.     if !size! GTR !maxSize! (
  9.         set /a n += 1, size = %%~zi
  10.     )
  11.     md %wjj%-!n! 2>nul
  12.     move "%%i" %wjj%-!n!\
  13. )
  14. pause
复制代码
谢谢

TOP

本帖最后由 WHY 于 2020-12-16 17:21 编辑

回复 5# bataiping


    cmd 数值计算本身就是弱项,如果单个文件超过 2GB,或者输入浮点数,会很麻烦。可以考虑其它办法。
Test.PS1
  1. $input = Read-Host('输入最大限制数(单位MB)');
  2. if( $input -notmatch '^(?:[1-9]\d+|\d)(?:\.\d+)?$' ){
  3.     echo '输入错误';
  4.     [Console]::ReadKey();
  5.     exit;
  6. }
  7. [Collections.ArrayList]$arr = @();
  8. $maxSize = 1024 * 1024 * $input;
  9. $n = 1001;
  10. $size = 0;
  11. $myPath = [IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path); #脚本所在目录
  12. $preFix = $myPath.Split('\')[-1] + '-';
  13. $file = dir -Literal $myPath -Filter *.pdf | ?{ $_ -is [IO.FileInfo] };
  14. for( $i=0; $i -lt $file.Count; $i++ ){
  15.     $size += $file[$i].Length;
  16.     if( $size -gt $maxSize ){
  17.         if( $i -gt 0 ){ $n++; }
  18.         $size = $file[$i].Length;
  19.     }
  20.     $fd = $myPath + '\' + $preFix + ('' + $n).SubString(1);    #新目录 = 前缀 + 3位数字
  21.     if( ![IO.Directory]::Exists($fd) ){
  22.         $null = md $fd;                                        #创建新目录
  23.     }
  24.     mv -Literal $file[$i].FullName -Dest ($fd + '\') -Force;   #移动文件
  25.     if( $file[$i].Length -gt $maxSize ){
  26.         [void]$arr.Add( $fd + ' 超过' + $input + 'MB' );
  27.     }
  28. }
  29. if( $arr.Count -gt 0 ){ sc -Literal ($myPath + '\error.Log') -Value $arr; }
  30. echo 'Done';
  31. [Console]::ReadKey();
复制代码

TOP

回复 4# akb4888


    你发一个新帖吧,有时间我帮你改。

TOP

回复 7# WHY


    好嘞,非常感谢!

TOP

回复 6# WHY


    很好用,首先谢谢老师
实际使用中还是有点偏差:
1,过大的文件还是要分文件夹的,自己占一个文件夹即可,文本中记录上“XXXX(该文件夹名称)大小超出限制
2,我之前修改的批处理中,命名方式当前文件夹名称-#,在您这个中用不来,我水平比较低,琢磨不出来该怎么改
3,我这边参考winrar的帮助,写了个压缩zip文件的命令,但是不知道为什么在这个文件中用不了
  1. for /f "delims=" %%i in ('dir /ad /b') do call :zip %%i
  2. :zip
  3. set var=%*
  4. "C:\Program Files\WinRAR\winrar" a -r -afzip %var% %var%
  5. EndLocal
复制代码
谢谢老师,费心了

TOP

返回列表