找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 43745|回复: 20

[文件操作] 批处理统计文件夹内的图片视频,计算大小时如何统计单位为G

[复制链接]
发表于 2024-8-7 16:13:38 | 显示全部楼层 |阅读模式
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /d %%a in (*) do (
  4.     set/a p=v=z=0
  5.     pushd "%%a"
  6.     for %%b in (*.jpg *.png *.bmp) do (
  7.         rem 计算放在这里,就是对所有图片大小的计算
  8.         set/a z+=%%~zb
  9.         if not "%%~nb"=="000" if not "%%~nb"=="00.1" if not "%%~nb"=="00.2" if not "%%~nb"=="00.3" (
  10.             set/a p+=1
  11.         )
  12.     )
  13.     for %%c in (*.mp4 *.avi *.mov *.mkv) do (
  14.         set/a v+=1,z+=%%~zc
  15.     )
  16.     set/a "sizeMB=z>>20"
  17.     set "sizeUnit=M"
  18.     if !sizeMB! geq 1024 (
  19.         set/a "sizeGB=sizeMB>>10"
  20.         set "sizeUnit=G"
  21.     )
  22.     popd
  23.     if !v! equ 0 (
  24.         rem 没有视频,只有图像
  25.         if "!sizeUnit!"=="G" (
  26.             ren "%%a" "%%a [!p!P-!sizeGB!!sizeUnit!]"
  27.         ) else (
  28.             ren "%%a" "%%a [!p!P-!sizeMB!!sizeUnit!]"
  29.         )
  30.     ) else if !p! equ 0 (
  31.         rem 没有图像,只有视频
  32.         if "!sizeUnit!"=="G" (
  33.             ren "%%a" "%%a [!v!V-!sizeGB!!sizeUnit!]"
  34.         ) else (
  35.             ren "%%a" "%%a [!v!V-!sizeMB!!sizeUnit!]"
  36.         )
  37.     ) else (
  38.         rem 既有图像又有视频
  39.         if "!sizeUnit!"=="G" (
  40.             ren "%%a" "%%a [!p!P!v!V-!sizeGB!!sizeUnit!]"
  41.         ) else (
  42.             ren "%%a" "%%a [!p!P!v!V-!sizeMB!!sizeUnit!]"
  43.         )
  44.     )
  45. )
  46. pause
复制代码
在这段代码中,脚本会统计当前文件夹下每一个子文件夹中的图像和视频的数量以及总大小,并将结果写在文件夹名称的后面,基本符合我的需求,但是早些时候统计文件夹大小时有时候大小会超过一个G,最后计算大小时单位他仍写成M,我使用了chatgpt,希望在统计大小时如果文件夹的内容超过一个G那么就以G为单位,但不知是我表述的有问题还是怎么样,这段代码里当文件内容超过一个计时它就记为1G,但是无论多大都记为1G,我希望能修改成超过1G时单位记为G,有多大就记为多大,比方说如果是1.46G就记为1.46G,不知道是否可行拜托各位大佬了
发表于 2024-8-7 20:40:43 | 显示全部楼层
本帖最后由 aloha20200628 于 2024-8-7 20:52 编辑

回复 1# walkercolin

以下代码存为 test.bat 置于图片和视频文件所在目录下运行...
批处只能处理不超过2GB的文件尺寸值,超出此限须调用外部计算方法解决,以下代码调用powershell方法(仅因其句式简捷)
运行结果会对每个目标目录更名,其更名格式》“原目录名 [xxxPyyyV-zzzMB]” 或 “原目录名 [xxxPyyyV-zzzGB]”,其中 xxx 或 yyy 可能=0(对应图片或视频文件数量=0)

  1. @echo off &setlocal enabledelayedexpansion &for /d %%d in (*) do (
  2.         pushd "%%d" &set/a "np=0,zp=0,nv=0,zv=0"
  3.         for /f "tokens=1-2 delims=个文件 " %%a in (
  4.                 '2^>nul dir /a-d/-c *.jpg *.png *.bmp^|find " 个文件 " ') do (set "np=%%a"&set "zp=%%b")
  5.         for /f "tokens=1-2 delims=个文件 " %%a in (
  6.                 '2^>nul dir /a-d/-c *.mp4 *.avi *.mov *.mkv^|find " 个文件 " ') do (set "nv=%%a"&set "zv=%%b")
  7.         for /f %%v in (
  8.                 ' powershell "if((!zp!+!zv!) -lt 1gb){[math]::round(-(!zp!+!zv!)/1mb,2)}else{[math]::round((!zp!+!zv!)/1gb,2)}" ') do set "zpv=%%v"
  9.         if "!zpv:~0,1!"=="-" (set "zpv=!zpv:~1!MB") else (set "zpv=!zpv!GB")
  10.         popd & ren "%%~fd" "%%d [!np!P!nv!V-!zpv!]"
  11. )
  12. endlocal&pause&exit/b
复制代码

评分

参与人数 1技术 +1 收起 理由
walkercolin + 1 乐于助人

查看全部评分

发表于 2024-8-8 01:01:42 | 显示全部楼层
本帖最后由 77七 于 2024-8-8 01:10 编辑

批处理统计文件夹内图片、视频数量及大小,并重命名文件夹
  1. @echo off
  2. rem 保存为ansi编码
  3. cd /d "%~dp0"
  4. rem 排除特定文件(000,00.1,00.2,00.3),不需要可以删除下一行
  5. set "_f=^|findstr /rvix /c:"00\.[123]\.[jpb][pnm][gp]" /c:"000\.[jpb][pnm][gp]""

  6. (for /f "delims=" %%d in ('dir /b /ad') do (
  7.         setlocal
  8.         pushd "%%d"
  9.         for /f %%a in ('dir /b /a-d *.jpg *.png *.bmp %_f% ^|find /c /v ""') do (
  10.                 set /a "1/%%a" && set P=%%aP
  11.         )
  12.         for /f %%a in ('dir /b /a-d *.mp4 *.avi *.mov *.mkv ^|find /c /v ""') do (
  13.                 set /a "1/%%a" && set V=%%aV
  14.         )
  15.         for /f "tokens=3" %%i in ('dir /-c /a-d *.jpg *.png *.bmp *.mp4 *.avi *.mov *.mkv ^|findstr /iec:" 字节"') do (
  16.                 for /f "tokens=1-2 delims=." %%a in ('powershell -c "$input = %%i; [math]::Round($input / (1024 * 1024 *1024), 2)"') do (
  17.                         set /a "1/%%a" && set "Z=%%a.%%bG" || for /f "delims=." %%c in ('powershell -c "%%i/1024/1024"') do set Z=%%cM
  18.                 )
  19.         )
  20.         popd
  21.         if defined Z (
  22.                 call echo ren "%%d" "%%d [%%p%%%%V%%-%%Z%%]"
  23.         )
  24.         endlocal
  25. )) 2>nul
  26. pause
复制代码

评分

参与人数 1技术 +1 收起 理由
walkercolin + 1 乐于助人

查看全部评分

 楼主| 发表于 2024-8-8 07:01:28 | 显示全部楼层
回复 2# aloha20200628
输出结果为[0P0V-0GB]
 楼主| 发表于 2024-8-8 07:01:48 | 显示全部楼层
回复 3# 77七
输出结果为[0P0V-0GB]
发表于 2024-8-8 09:18:49 | 显示全部楼层
本帖最后由 aloha20200628 于 2024-8-8 10:28 编辑

回复 4# walkercolin

更正》2楼批处代码应置于 ‘图片+视频子目录’ 的上一级目录中运行,如同一楼代码的运行位置
模拟一楼题型的文件及目录,用2楼代码已测试通过...
发表于 2024-8-8 10:15:44 | 显示全部楼层
回复 5# walkercolin





0P0V0G这三个0在任何情况下都是不可能出现的
发表于 2024-8-8 16:24:07 | 显示全部楼层
本帖最后由 ppll2030 于 2024-8-8 16:28 编辑

回复 1# walkercolin


    用set /a 的结果都是整数,而另一个问题,bat计算有2GB的限制,综合两点,你的计算方法需要换一个。
试试:把16行的  set/a "sizeMB=z>>20"  替换为:
  1. for /f %%v in ('powershell "[math]::Round(!z! / (1073*1000), 2)"') do set "sizeMB=%%v"
复制代码
把19行的   set/a "sizeGB=sizeMB>>10"  替换为:
  1. for /f %%v in ('powershell "[math]::Round(!z! / (1073*1000*1000), 2)"') do set "sizeGB=%%v"
复制代码
 楼主| 发表于 2024-8-8 18:04:37 | 显示全部楼层
回复 8# ppll2030
有用的,但是这样一来,那些没达到1G的文件夹也仍然按照G的单位进行计算,我希望没超过1G的按M单位,超过的按G单位是否可行呢
发表于 2024-8-8 18:13:24 | 显示全部楼层
本帖最后由 ppll2030 于 2024-8-8 18:34 编辑

回复 9# walkercolin


    你原来的代码是否能正常判断显示MB或GB?因为我没细看,我只是提供了计算方式的修改。
如果if的判断有误,那就还要修改,不如直接用楼上大佬的完整代码了

看了一下,if判断数值,不能有小数点。否则也会报错。
把16行的  set/a "sizeMB=z>>20"  替换为:
  1. for /f %%v in ('powershell "[math]::Round(!z! / (1073*1000), 0)"') do set "sizeMB=%%v"
复制代码
保留整数,方便你的IF做判断。
19行,正常替换,保留两位小数。
这样应该没有问题了。

评分

参与人数 1技术 +1 收起 理由
walkercolin + 1 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2024-8-8 19:07:16 | 显示全部楼层
本帖最后由 aloha20200628 于 2024-8-8 19:14 编辑

回复 1# walkercolin

      一楼代码中第8,14,16行,一旦文件尺寸值(字节单位)或累加值(字节单位)超过32位整数限就会失误,此乃为何要调用外部计算方法并重写代码的原因
      重写代码不仅是简单重复调用外部计算方法(尤其是在最内层循环体内复用其效率会明显降低),还要兼顾代码的效率,从dir简报中直接获取目标文件总数及其文件尺寸累加值,应该是一条捷径...
 楼主| 发表于 2024-8-8 21:32:25 | 显示全部楼层
回复 10# ppll2030
完美了,感谢大佬帮助愚钝完全不懂什么代码的我拨云见雾,您简直就是当代丹尼斯·里奇,再次感谢您
发表于 2024-8-8 22:02:36 | 显示全部楼层
回复 12# walkercolin


    嗯。楼上的大佬提醒了。你的前半段统计体积,还是用的set/a,所以2GB的限制还是存在的,建议更换dir来获取
发表于 2024-8-9 18:19:26 | 显示全部楼层
只用bat,适合粗略统计。数值不准确,也无需保留小数点后两位了
  1. @echo off
  2. rem 保存为ansi编码
  3. cd /d "%~dp0"
  4. for %%a in ("000" "00.1" "00.2" "00.3") do (
  5.         set _"%%~a"=1
  6. )
  7. set -=-
  8. for /f "delims=" %%d in ('dir /b /ad') do (
  9.         set f=%%d
  10.         setlocal enabledelayedexpansion
  11.         pushd "!f!"
  12.         for %%i in (*.jpg *.png *.bmp) do (
  13.                 if not defined _"%%~ni" (
  14.                         set /a p+=1
  15.                 )
  16.                 set /a m=%%~zi/1024,n+=m
  17.         )
  18.         set n/=1024
  19.         for %%i in (*.mp4 *.avi *.mov *.mkv) do (
  20.                 set /a v+=1
  21.                 set t=%%~zi
  22.                 set t=!t:~0,-3!
  23.                 if "!t!" neq "" (
  24.                         set /a n+=!t!/1024
  25.                 )
  26.         )
  27.         popd
  28.         for %%a in (P V) do (
  29.                 if defined %%a (
  30.                         set str=!str!!%%a!%%a
  31.                 )
  32.         )
  33.         if !n! gtr 1024 (
  34.                 set /a x=n/1024
  35.                 echo ren "!f!" "!f![!str!-!x!G]"
  36.         ) else if !n! neq 0 (
  37.                 echo ren "!f!" "!f![!str!-!n!M]"
  38.         )
  39.         endlocal
  40. )
  41. pause
复制代码
发表于 2024-8-10 14:23:55 | 显示全部楼层
本帖最后由 WHY 于 2024-8-14 11:50 编辑

Test.ps1
  1. $srcFolder = 'E:\Test\';                  #源目录路径

  2. $ext1 = @{'.jpg'=1; '.bmp'=1; '.png'=1; '.tif'=1; '.jpeg'=1} #图片扩展名
  3. $name = @{'000'=1; '00.1'=1; '00.2'=1; '00.3'=1}             #需要排除的图片名称
  4. $ext2 = @{'.mp4'=1; '.avi'=1; '.mov'=1; '.mkv'=1}            #视频扩展名
  5. $Hash = @{}

  6. Function Get-Size($sz) {
  7.     If ($sz -ge 1GB) {
  8.         return ($sz/1GB).ToString('0.00G');
  9.     } ElseIf ($sz -ge 1MB) {
  10.         return ($sz/1MB).ToString('0.00M');
  11.     } Else {
  12.         return ($sz/1KB).ToString('0.00K');
  13.     }
  14. }

  15. forEach ($f In (Get-ChildItem -Literal $srcFolder -Recurse -File -Filter *.*)) {
  16.     $fd = $f.DirectoryName;                       #目录名
  17.     If ($ext1.Contains($f.Extension) -and !$name.Contains($f.BaseName)) {
  18.         If (!$Hash.Contains($fd)) {
  19.             $Hash.Add($fd, @(1, 0, $f.Length));   #添加哈希表,键=目录名;值=数组
  20.         } Else {
  21.             $Hash[$fd][0] += 1;                   #图片个数
  22.             $Hash[$fd][2] += $f.Length;           #文件大小
  23.         }
  24.     } ElseIf ($ext2.Contains($f.Extension)) {
  25.         If (!$Hash.Contains($fd)) {
  26.             $Hash.Add($fd, @(0, 1, $f.Length));   #添加哈希表,键=目录名;值=数组
  27.         } Else {
  28.             $Hash[$fd][1] += 1;                   #视频个数
  29.             $Hash[$fd][2] += $f.Length;           #文件大小
  30.         }
  31.     }
  32. }

  33. $keys = $Hash.GetEnumerator().Name;
  34. [Array]::Sort($keys);                             #排序,避免重命名失败

  35. for ($i=$keys.Count-1; $i -ge 0; $i--) {
  36.     $k = $keys[$i];
  37.     $sufFix = '[' + $Hash[$k][0] + 'P' + $Hash[$k][1] + 'V-' + (Get-Size $Hash[$k][2]) + ']';   #后缀
  38.     $sufFix = $sufFix -replace '(?-i)(?<=\D)0[PV]';       #删掉0P、0V
  39.     $newName = $k.Split('\')[-1] + $sufFix;
  40.     Rename-Item -Literal $k -NewName $newName;            #重命名
  41. }
  42. pause
复制代码

评分

参与人数 1技术 +1 收起 理由
buyiyang + 1 good catch

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 21:06 , Processed in 0.027050 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表