LuigiKraken
LuigiKraken

Reputation: 17

List combined size of all files with type in batch

I'm new to batch scripts and I wanted to know if it's possible to list the combined size of all files with type in a text file.

For example: if there are two .mp3 files each of 1GB the output should be

MP3 2147483648 bytes

I know how to list all files in a directory or just list files of one type. The problem I have is adding the sizes of of similar file types together.

Here's my code so far:

@echo off

Rem This is for listing down all the files in the directory Program files 

set mypath=%cd%

dir "%mypath%" *.mp3 > %mypath%\lists.txt 
echo program completed

Upvotes: 0

Views: 590

Answers (3)

Aacini
Aacini

Reputation: 67216

It is very simple to adjust the Batch code in order to manage any number of digits in the result. This solution allows to manage up to 16 digits in the accumulated results:

@echo off
setlocal EnableDelayedExpansion

set "digits=8"

rem Assemble the factor with the proper number of digits
set "factor=1"
for /L %%i in (1,1,%digits%) do set "factor=!factor!0"

rem Accumulate size of all extensions in 2 groups of %digits% digits each
for %%a in (*.*) do (
   set "size=%factor%%%~Za"
   set /A "low[%%~Xa]+=1!size:~-%digits%!-factor, carry=low[%%~Xa]/factor, low[%%~Xa]%%=factor"
   set "size=%%~Za"
   set "size=!size:~0,-%digits%!"
   set /A "high[%%~Xa]+=carry+size"
)

rem Show results
for /F "tokens=2,3 delims=[.]=" %%a in ('set high[') do (
   if %%b neq 0 (
      set "low=%factor%!low[.%%a]!"
      echo %%a %%b!low:~-%digits%! bytes
   ) else (
      echo %%a !low[.%%a]! bytes
   )
)

Output example:

C:\Users\Antonio\Documents\tests> dir *.mp3
 El volumen de la unidad C no tiene etiqueta.
 El número de serie del volumen es: 0895-160E

 Directorio de C:\Users\Antonio\Documents\tests

07/07/2010  09:58 a. m.        14,336,418 BigFile.mp3
01/05/2018  03:01 p. m.       143,364,180 BigFile2.mp3
01/05/2018  03:13 p. m.     1,433,641,800 BigFile3.mp3
07/07/2010  09:58 a. m.        14,336,418 BigFileB.mp3
               4 archivos  1,605,678,816 bytes
               0 dirs  390,478,827,520 bytes libres

C:\Users\Antonio\Documents\tests> test.bat
bat 200759 bytes
csv 20412 bytes
mp3 1605678816 bytes
pdf 62799 bytes
txt 1036041 bytes

Upvotes: 2

user6811411
user6811411

Reputation:

As long as the cumulated size doesn't exceed the integer limit (2,147,483,647),
this small batch might do:

:: Q:\Test\2018\05\01\SO_50117738.cmd
@Echo off & SetLocal
Pushd "C:\Test"
For /f "delims==" %%A in ('2^>Nul Set Ext[') Do Set "%%A="
For /f "delims=" %%A in ('Dir /B/A-D') Do Set /A "Ext[%%~xA]+=%%~zA/1024"
Set Ext[

Sample output now for whole kbytes (bytes truncated)

> Q:\Test\2018\05\01\SO_50117738.cmd
Ext[.cmd]=0
Ext[.html]=2
Ext[.ps1]=11
Ext[.sh]=3
Ext[.txt]=3
Ext[.vbs]=0
Ext[]=0

> powershell -nop -nol "$ext=@{};ls -File|%{$ext.\"$($_.Extension)\"+=$_.Length};$ext"

Name                           Value
----                           -----
.txt                           4567
.ps1                           12827
.vbs                           435
.cmd                           2000
.sh                            4605
.html                          3536
                               219

Another one with a bit more control over the output

> powershell -nop -nol "$ext=@{};ls -File|%{$ext.\"$($_.Extension)\"+=$_.Length};$ext.GetEnumerator()|sort Name|%{'{0,-6} {1,12}' -f $_.Name,$_.Value}"
                219
.cmd           2000
.html          3536
.ps1          12827
.sh            4605
.txt           4567
.vbs            435

Upvotes: 0

Compo
Compo

Reputation: 38604

I would suggest that this task is less than simple for somebody new to batch scripting and will offer a solution which leverages PowerShell instead.

@Echo Off
Set "MyDir=%~1"
If Defined MyDir CD /D "%MyDir%" 2>Nul || Exit /B
Dir /B/A-D >Nul 2>&1 || Exit /B
(For /F "Skip=3 Tokens=1-2 Delims=. " %%A In ('PowerShell -NoP -NoL^
 "GCI -Ex 'lists.txt' -Fo|?{!$_.PSIsContainer}|Group Extension|"^
 "Select Name,@{n='TS';e={(($_.Group|Measure Length -Sum).Sum)}}"
') Do Echo %%A %%B bytes)>"%__CD__%lists.txt"

With this you'd either:

  • replace %~1 with your target directory.
    (do not touch the doublequotes)

or:

  • send your target directory as an argument to the script.

If neither are done, it should produce output for the current directory.

(Please note that because the output file overwrites any existing one in the target directory it would include an old size of itself in its own results. For this reason I have added an exclusion, (untested), as part of the PowerShell commands)

Upvotes: 0

Related Questions