Reputation: 17
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
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
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
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:
%~1
with your target directory.or:
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