如何在Windows批处理脚本中检查文件大小?

73

我想要一个批处理文件,它可以检查文件的filesize

如果文件大小大于%somany% kbytes,它应该使用GOTO重定向到其他地方。

例如:

[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
14个回答

106

如果文件名被用作批处理文件的参数,您只需要使用%~z1(其中1代表第一个参数)。

如果文件名不是参数,您可以尝试以下操作:

@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
)

8
请问"usebackq"选项是如何起作用的?这似乎与文件大小无关,但如果我去除它,程序就无法运行。 - JoelFan
14
没有使用usebackq,单引号表示命令而不是字符串(运行FOR /? 以获取详细信息)。另一个选择(更好地处理文件名中的空格)是使用:FOR /F "tokens=*" %%A IN ("%file%") DO ... - Anders
嗨@Anders,你能告诉我当我有多个文件时如何执行相同的操作吗?比如说,如果我的文件小于2kb,那么我想将它移动到另一个文件夹中。我的结果应该测试路径中的每个文件并进行验证。 - vijay kumar
顺便提一下:在此之前,你应该检查文件是否存在。否则,文件大小将只是一个空字符串...我花了一段时间才注意到这一点。 - Matthias W.
没关系...对于我来说,甚至将其写入现有文件的变量中都无法实现... - Matthias W.

25

我喜欢@Anders的答案,因为它对%~z1秘密酱的解释很好。 然而,正如指出的那样,这仅在将文件名作为批处理文件的第一个参数传递时才有效。

@Anders通过使用FOR解决了这个问题,这是一个很棒的一行代码修复方法,但是有点难以阅读。

相反,我们可以通过使用CALL回到更简单的答案来使用%~z1。 如果您将文件名存储在环境变量中,并将其用作批处理文件中例程的参数,则它将成为%1:

@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

我一直对J. Bouvrie关于32位限制的担忧感到好奇。他似乎在谈论使用LSS时存在的一个问题,而不是文件大小逻辑本身的问题。为了解决J. Bouvrie的顾虑,我已经重写了解决方案,改用填充字符串比较:

@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

11

我更喜欢使用DOS功能。 对我来说感觉更清洁。

SET SIZELIMIT=1000
CALL :FileSize %1 FileSize
IF %FileSize% GTR %SIZELIMIT% Echo Large file

GOTO :EOF

:FileSize
SET %~2=%~z1

GOTO :EOF

DOS中没有函数和:eof,这些是Windows cmd.exe的特性。它们完全不同。 - phuclv
2
除了不支持DOS之外,这是最干净的解决方案。使用call :label获取可用的编号参数。 - NiKiZe
FYI 我在脚本顶部不小心加了 SET FileSize=0,这会导致一些问题。可能会产生一个外部作用域变量,在“函数调用”返回时仍然保持不变。希望能帮到其他人... - Razzle

11

%~z1 会展开为批处理文件的第一个参数的大小。请参阅

C:\> call /?

并且

C:\> if /?

简单示例:

@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

9
如果您的%file%是一个输入参数,您可以使用%~zN,其中N是参数的编号。
例如,一个包含以下内容的test.bat
@echo %~z1

该命令将显示第一个参数的大小,因此如果您使用"test myFile.txt",它将显示相应文件的大小。


7

另一个例子

  FOR %I in (file1.txt) do @ECHO %~zI

我认为你需要将 %I 改为 %%I,将 %~zI 改为 %%~zI,这样它才能在批处理文件中正常工作。 - ZiyadCodes

4

像往常一样,VBScript可供您使用......


Set objFS = CreateObject("Scripting.FileSystemObject")
Set wshArgs = WScript.Arguments
strFile = wshArgs(0)
WScript.Echo objFS.GetFile(strFile).Size & " bytes"

请将文件另存为filesize.vbs,然后在命令行中输入:

C:\test>cscript /nologo filesize.vbs file.txt
79 bytes

使用批处理中的for循环来获取返回结果。

3

经过几次“尝试和测试”迭代,我找到了一种方法(目前还没有在这里呈现),可以在循环变量中获取文件大小(而不是命令行参数):

for %%i in (*.txt) do (
    echo %%~zi
)

~z 可以获取文件的大小


2
创建一个名为 GetFileSize.bat 的一行批处理文件,其中包含以下内容。
GetFileSize=%~z1

然后调用它。
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.

您甚至可以动态创建测试文件以消除烦人的必需文件,注意echo语句中的双百分号:

echo set GetFileSize=%%~z1 > %temp%\GetFileSize.bat
call %temp%\GetFileSize  myfile.txt
if (%GetFileSize) GTR 1000  goto Too_Much_Data
rem etc

这种解决方案是反意大利面代码。非常优秀。但会增加硬盘写入量。需要检查使用次数。

2
这是我使用本地Windows shell命令评估文件大小而不使用VB / perl等的解决方案:
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  
    )
)  

这不是最干净的解决方案,但它能完成工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接