Obtenga el tamaño de un directorio en ‘MB’ usando el archivo por lotes

Quiero que el tamaño del directorio indique C:\Temp en MB usando el archivo por lotes. No necesito tamaños de directorios o archivos secundarios, sino el tamaño del directorio en sí.

Encontré una respuesta en Cómo listar todas las carpetas con el tamaño a través del archivo por lotes

pero me da tamaño en bytes y el de subcarpetas. Entonces mi pregunta es:

¿Cómo obtener el tamaño del directorio en MB ?

Puede hacerlo con un script híbrido [Batch / Vbscript] como este:

 @echo off set Folder="C:\temp" echo The size of %Folder% is Call :GetSize %Folder% pause :GetSize ( echo wscript.echo GetSize("%~1"^) echo Function GetSize(MyFolder^) echo Set fso = CreateObject("Scripting.FileSystemObject"^) echo Set objFolder= fso.GetFolder(MyFolder^) echo GetSize = FormatSize(objFolder.Size^) echo End Function echo '******************************************************************* echo 'Function to format a number into typical size scales echo Function FormatSize(iSize^) echo aLabel = Array("bytes", "KB", "MB", "GB", "TB"^) echo For i = 0 to 4 echo If iSize ^> 1024 Then echo iSize = iSize / 1024 echo Else echo Exit For echo End If echo Next echo FormatSize = Round(iSize,2^) ^& " " ^& aLabel(i^) echo End Function echo '******************************************************************* )>%tmp%\Size.vbs Cscript /NoLogo %tmp%\Size.vbs Del %tmp%\Size.vbs Exit /b 

Edición: el 30/03/2016 a las 12: 11

Y este es un buen truco

el truco de Liviu para incrustar vbscode en lotes sin archivos temporales

Acabo de descubrir de npocmaka gracias a él

 @echo off Set Folder="c:\temp" @cScript.EXE //noLogo "%~f0?.WSF" %Folder% //job:info %~nx0%* pause @exit /b 0    
 @echo off ::robocopy "%~1" %TEMP% /S /L /BYTES /XJ /NFL /NDL /NJH for /f "tokens=2 delims=: " %%a in (' robocopy "%~1" %TEMP% /S /L /BYTES /XJ /NFL /NDL /NJH ^| find "Bytes" ') do set "bytes=%%a" ::1048576 set "beginJS=mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(" set "endJS=));"" for /f %%N in ( '%beginJS% %bytes%/1048576 %endJS%' ) do set mb=%%N echo mb=%mb% 

Se necesita un argumento: la carpeta cuyo tamaño desea calcular

Aquí hay una solución de archivo por lotes puro (consulte las observaciones en el código para algunas breves explicaciones):

 @echo off setlocal EnableExtensions DisableDelayedExpansion rem Define constants here: set /A DIVISOR=1024 & rem (1024 Bytes = 1 KBytes, 1024 KBytes = 1 MByte,...) set "ROUNDUP=#" & rem (set to non-empty value to round up results) rem Get size of directory given as command line argument: for /F "tokens=2 delims=: " %%B in (' robocopy "%~1" "%~1" "*.*" /L /S /XJ /BYTES /NP /NFL /NDL /NJH ^| ^ find /I "Bytes" ') do set "BYTES=%%B" if not defined BYTES set "BYTES=0" rem Display result in Bytes and divide it to get KBytes, MBytes, etc.: call :DIVIDE %BYTES% 1 RESULT echo( Bytes: %RESULT% call :DIVIDE %RESULT% %DIVISOR% RESULT REST if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1 echo(KBytes: %RESULT% call :DIVIDE %RESULT% %DIVISOR% RESULT REST if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1 echo(MBytes: %RESULT% call :DIVIDE %RESULT% %DIVISOR% RESULT REST if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1 echo(GBytes: %RESULT% endlocal exit /B :DIVIDE val_dividend val_divisor [ref_result] [ref_remainder] rem Divide a huge number exceeding the 32-bit limitation rem by a 32-bit number in the range from 1 to 1000000000; rem the result might also exceed the 32-bit limitation. setlocal EnableDelayedExpansion set "DIVIDEND=%~1" set "DIVISOR=%~2" set "QUOTIENT=%~3" set "REMAINDER=%~4" rem Check whether dividend and divisor are given: if not defined DIVIDEND ( >&2 echo(Too few arguments, dividend missing^^! exit /B 2 ) else if not defined DIVISOR ( >&2 echo(Too few arguments, divisor missing^^! exit /B 2 ) rem Check whether dividend is purely numeric: for /F "tokens=* delims=0123456789" %%N in ("!DIVIDEND!") do ( if not "%%N"=="" ( >&2 echo(Dividend must be numeric^^! exit /B 2 ) ) rem Convert divisor to numeric value without leading zeros: for /F "tokens=* delims=0" %%N in ("%DIVISOR%") do set "DIVISOR=%%N" set /A DIVISOR+=0 rem Check divisor against its range: if %DIVISOR% LEQ 0 ( >&2 echo(Divisor value must be positive^^! exit /B 1 ) else if %DIVISOR% GTR 1000000000 ( >&2 echo(Divisor value exceeds its limit^^! exit /B 1 ) set "COLL=" & set "NEXT=" & set /A INDEX=0 rem Do a division digit by digit as one would do it on paper: :LOOP if "!DIVIDEND:~%INDEX%,1!"=="" goto :CONT set "NEXT=!NEXT!!DIVIDEND:~%INDEX%,1!" rem Remove trailing zeros as such denote octal numbers: for /F "tokens=* delims=0" %%N in ("!NEXT!") do set "NEXT=%%N" set /A NEXT+=0 set /A PART=NEXT/DIVISOR set "COLL=!COLL!!PART!" set /A NEXT-=PART*DIVISOR set /A INDEX+=1 goto :LOOP :CONT rem Remove trailing zeros as such denote octal numbers: for /F "tokens=* delims=0" %%N in ("%COLL%") do set "COLL=%%N" if not defined COLL set "COLL=0" rem Set return variables or display result if none are given: if defined QUOTIENT ( if defined REMAINDER ( endlocal set "%REMAINDER%=%NEXT%" ) else ( endlocal ) set "%QUOTIENT%=%COLL%" ) else ( endlocal echo(%COLL% ) exit /B 

Básicamente, el tamaño de los contenidos del directorio dado como argumento de línea de comando es recostackdo por robocopy , similar al enfoque de npocmaka ; el tamaño resultante en Bytes se almacena en la variable BYTES .

Después, se realizan varias llamadas a la subrutina, cada una para dividir el resultado entre 1024 para obtener el tamaño en KBytes, luego MBytes y GBytes.

Los valores resultantes de las divisiones se incrementan en 1 si hay un rest para redondear los tamaños (similar a Windows Explorer, que por ejemplo muestra 1 KB para archivos muy pequeños). Puede desactivar esta característica configurando la variable ROUNDUP en una cadena vacía, lo que lleva al redondeo hacia abajo.


Enfoque de división

Como el comando set /A (y su operador de división / ) puede manejar enteros de 32 bits (firmados) solamente, la subrutina :DIVIDE realiza la división real como lo haría en papel. El dividendo (que es el número que se divide) se trata como una cadena, por lo que se puede exceder el rango de 32 bits; el divisor (que es el número para dividir) no debe excederlo; más bien debe estar en el rango de 1 a 1000000000 . El bucle en :LOOP consiste en goto :LOOP y un goto :CONT condicional goto :CONT constituye una estructura tipo bucle while que itera a través de todas las figuras decimales del dividendo y termina después de que se ha alcanzado el último.

La subrutina espera al menos dos argumentos: los valores del dividendo y el divisor. Acepta incluso dos más: el nombre de una variable para mantener el cociente (es decir, el resultado de la división) y otro para contener el rest. Si no se proporcionan argumentos opcionales, el cociente se muestra en la consola.

si necesita valores exactos, busque otra opción. Pero si solo necesita un valor aproximado (corte, no redondeado, no 1024 como divisor sino 1000 solamente):

 @echo off for /f "tokens=2 delims=," %%a in ('dir *^|findstr /e "Bytes"') do ( for /f "delims= " %%i in ("%%a") do set size=%%i ) echo size in Bytes: %size% echo that's about %size:~0,-4% KB echo or about %size:~0,-8% MB echo or about %size:~0,-12% GB 

Ventaja: esto es solo manipulación de cadenas, no incluye matemática, por lo que funciona incluso fuera del Entero de 32 bits (que estaría limitado a tamaños de hasta aproximadamente 2 GB).