问题
I want to have a batch file which checks what the filesize
is of a file.
If it is bigger than %somany% kbytes,
it should redirect with GOTO to somewhere else.
Example:
[check for filesize]
IF %file% [filesize thing Bigger than] GOTO No
echo Great! Your filesize is smaller than %somany% kbytes.
pause
exit
:no
echo Um... You have a big filesize.
pause
exit
回答1:
If the file name is used as a parameter to the batch file, all you need is %~z1
(1 means first parameter)
If the file name is not a parameter, you can do something like:
@echo off
setlocal
set file="test.cmd"
set maxbytesize=1000
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
if %size% LSS %maxbytesize% (
echo.File is ^< %maxbytesize% bytes
) ELSE (
echo.File is ^>= %maxbytesize% bytes
)
回答2:
I like @Anders answer because the explanation of the %~z1 secret sauce. However, as pointed out, that only works when the filename is passed as the first parameter to the batch file.
@Anders worked around this by using FOR
, which, is a great 1-liner fix to
the problem, but, it's somewhat harder to read.
Instead, we can go back to a simpler answer with %~z1 by using CALL
.
If you have a filename stored in an environment variable it will become
%1 if you use it as a parameter to a routine in your batch file:
@echo off
setlocal
set file=test.cmd
set maxbytesize=1000
call :setsize %file%
if %size% lss %maxbytesize% (
echo File is less than %maxbytesize% bytes
) else (
echo File is greater than or equal %maxbytesize% bytes
)
goto :eof
:setsize
set size=%~z1
goto :eof
I've been curious about J. Bouvrie's concern regarding 32-bit limitations. It appears he is talking about an issue with using LSS
not on the filesize logic itself. To deal with J. Bouvrie's concern, I've rewritten the solution to use a padded string comparison:
@echo on
setlocal
set file=test.cmd
set maxbytesize=1000
call :setsize %file%
set checksize=00000000000000000000%size%
set checkmaxbytesize=00000000000000000000%maxbytesize%
if "%checksize:~-20%" lss "%checkmaxbytesize:~-20%" (
echo File is less than %maxbytesize% bytes
) else (
echo File is greater than or equal %maxbytesize% bytes
)
goto :eof
:setsize
set size=%~z1
goto :eof
回答3:
%~z1
expands to the size of the first argument to the batch file. See
C:\> call /?
and
C:\> if /?
Simple example:
@ECHO OFF
SET SIZELIMIT=1000
SET FILESIZE=%~z1
IF %FILESIZE% GTR %SIZELIMIT% Goto No
ECHO Great! Your filesize is smaller than %SIZELIMIT% kbytes.
PAUSE
GOTO :EOF
:No
ECHO Um ... You have a big filesize.
PAUSE
GOTO :EOF
回答4:
I prefer to use a DOS function. Feels cleaner to me.
SET SIZELIMIT=1000
CALL :FileSize %1 FileSize
IF %FileSize% GTR %SIZELIMIT% Echo Large file
GOTO :EOF
:FileSize
SET %~2=%~z1
GOTO :EOF
回答5:
If your %file%
is an input parameter, you may use %~zN
, where N
is the number of the parameter.
E.g. a test.bat
containing
@echo %~z1
Will display the size of the first parameter, so if you use "test myFile.txt
" it will display the size of the corresponding file.
回答6:
As usual, VBScript is available for you to use.....
Set objFS = CreateObject("Scripting.FileSystemObject")
Set wshArgs = WScript.Arguments
strFile = wshArgs(0)
WScript.Echo objFS.GetFile(strFile).Size & " bytes"
Save as filesize.vbs
and enter on the command-line:
C:\test>cscript /nologo filesize.vbs file.txt
79 bytes
Use a for
loop (in batch) to get the return result.
回答7:
Another example
FOR %I in (file1.txt) do @ECHO %~zI
回答8:
Create a one line batch file GetFileSize.bat containing
GetFileSize=%~z1
then call it
call GetFileSize myfile.txt
if (%GetFileSize) == () goto No_File
if (%GetFileSize) == (0) goto No_Data
if (%GetFileSize) GTR 1000 goto Too_Much_Data
rem Etc.
You can even create your test file on the fly to eliminate the pesky required file, note the double percent in the echo statement:
echo set GetFileSize=%%~z1 > %temp%\GetFileSize.bat
call %temp%\GetFileSize myfile.txt
if (%GetFileSize) GTR 1000 goto Too_Much_Data
rem etc
This latter solution is antispaghetti. So nice. However, more disk writes. Check use count.
回答9:
Just saw this old question looking to see if Windows had something built in. The ~z thing is something I didn't know about, but not applicable for me. I ended up with a Perl one-liner:
@echo off
set yourfile=output.txt
set maxsize=10000
perl -e "-s $ENV{yourfile} > $ENV{maxsize} ? exit 1 : exit 0"
rem if %errorlevel%. equ 1. goto abort
if errorlevel 1 goto abort
echo OK!
exit /b 0
:abort
echo Bad!
exit /b 1
回答10:
This was my solution for evaluating file sizes without using VB/perl/etc. and sticking with native windows shell commands:
FOR /F "tokens=4 delims= " %%i in ('dir /-C %temp% ^| find /i "filename.txt"') do (
IF %%i GTR 1000000 (
echo filename.txt filesize is greater than 1000000
) ELSE (
echo filename.txt filesize is less than 1000000
)
)
Not the cleanest solution, but it gets the job done.
回答11:
Important to note is the INT32 limit of Batch: 'Invalid number. Numbers are limited to 32-bits of precision.'
Try the following statements:
IF 2147483647 GTR 2147483646 echo A is greater than B (will be TRUE)
IF 2147483648 GTR 2147483647 echo A is greater than B (will be FALSE!)
Any number greater than the max INT32 value will BREAK THE SCRIPT! Seeing as filesize is measured in bytes, the scripts will support a maximum filesize of about 255.9999997615814 MB !
回答12:
After a few "try and test" iterations I've found a way (still not present here) to get size of file in cycle variable (not a command line parameter):
for %%i in (*.txt) do (
echo %%~z%i
)
回答13:
Just an idea:
You may get the filesize by running command "dir":
>dir thing
Then again it returns so many things.
Maybe you can get it from there if you look for it.
But I am not sure.
来源:https://stackoverflow.com/questions/1199645/how-can-i-check-the-size-of-a-file-in-a-windows-batch-script