3

I have a working for loop to print all zip file's name under one working directory:

@echo off
setlocal

for %%i in (*.zip) do (
    echo %%i
    )

I have another working if block to check and print out a zip file size :

echo set FileSize=%%~z1 > %temp%\GetFileSize.bat
call %temp%\GetFileSize  "720P_1500K_101399042.zip"
if %FileSize% GTR 1000 (
    echo %FileSize% is greater than 1000
    ) else (
    echo %FileSize% is NOT greater than 1000
    )

Now, I am trying to combine these two pieces together to have a for loop to get all zip files under the working directory and at the same time use the if block to check the file size and then print out the size. But I was told: 1000 was unexpected at this time. why?

for %%i in (*.zip) do (
    echo %%i
    echo set FileSize=%%~z1 > %temp%\GetFileSize.bat
    call %temp%\GetFileSize  "%%i"
    if %FileSize% GTR 1000 (
        echo %FileSize% is greater than 1000
    ) else (
        echo %FileSize% is NOT greater than 1000
    )
    )
  • 1
    technically, because %filesize% is not defined, so the if syntax is invalid. You'd need delayed expansion – Stephan Jul 27 '20 at 6:58
  • @Stephan you are right. if I replace all %FilesSize% with !FileSize!, the error goes away but the result is wrong. that is the actual file size is not used in the if block correctly. – peterboston Jul 27 '20 at 14:00
  • it is used as you programmed it. The way you created the secondary batch file, added a space to the size, which forces if to string mode (where 2 is "greater" than 1000) (Note: this happens only with a delayed !variable! - with a "normal" %variable%, if can correct the additional space). Change to (echo set FileSize=%%~z1) > %temp%\GetFileSize.bat to avoid that space. Welcome to batch - the world of pain and headache. – Stephan Jul 27 '20 at 16:48
  • @Stephan I added the bracket to the "echo set ..." line as your reply. The result is the same: a bigger file print out "... NOT greater than 1000" – peterboston Jul 28 '20 at 2:05
  • 1
    run with echo off and see what's exactly executed (you should see the actual filesize) btw: you did setlocal enabledelayedexpansion before using delayed expansion, did you?) – Stephan Jul 29 '20 at 18:44
3

I will use powershell for this:

Get-ChildItem "Filepath" -Filter *.zip | ForEach {
  "$_.Name"
  If($_.Length -gt 1000){
    Write-Host "$($_.Length) is greater than 1000"
  }
  Else {
    Write-Host "$($_.Length) is NOT greater than 1000"
  }
}

Or if you strictly want to use batch, then why pass it to another batch file? Directly do it:

@echo off
setlocal
for %%i in (*.zip) do (
    echo %%i
    if %%~zi GTR 1000 (
        echo %%~zi is greater than 1000
    ) else (
        echo %%~zi is NOT greater than 1000
    )
)
  • @peterboston check the snippets now – Wasif Hasan Jul 26 '20 at 7:20
  • thank you. it works now. I find inside the for loop I need to modify the file to get a new file, saying COPY /b something+"%%i" "%%~ni-new". how can I get the new file's size in the if block. – peterboston Jul 26 '20 at 16:29
  • 1
    with another forloop: for %%j in ("%%~ni-new") do set "newsize=%%~zj" – Stephan Jul 27 '20 at 16:56
  • 1
    Thanks @Stephan for the note. – Wasif Hasan Jul 28 '20 at 0:29
  • @Stephan you are right, add another for loop does the trick. but cannot get the correct result if set "newsize=%%~zj" is used. I have to use %%~zj in the if condition directly – peterboston Jul 28 '20 at 2:44
3

You can try something like:

  • For to accept your arguments (%1, %2, %3, %n...) and echoing name and size:
@echo off && setlocal enabledelayedexpansion

if not "%~x1" == ".zip" (
     set "_loops=*.zip" ) else set "_loops=%*" 
     
set^ "_bit=is greater" && for %%i in (!_loops!) do (
     if not %%~zi gtr 1000 set "_bit=!_bit: = NOT !"
     echo\File %%~nxi ^| Size %%~zi !_bit! than 1000
     set "_bit=is greater"
   )

endlocal && goto=:EOF
  • Little more simple and with arguments too:
@echo off

if not "%~x1"==".zip" (
     set "_zip=*.zip") else set "_zip=%*" 
     
for %%i in (%_zip%)do if %%~zi gtr 1000 (
     echo\%%~zi is greater than 1000
     )else echo\%%~zi is NOT greater
  • One option that only echoing name and size:
@echo off && setlocal enabledelayedexpansion

set^ "_bit=is greater" &&  for %%i in ("*.zip") do (
     if not %%~zi gtr 1000 set "_bit=!_bit: = NOT !"
     echo\File %%~nxi ^| Size %%~zi !_bit! than 1000
     set "_bit=is greater"
   )

endlocal && goto=:EOF

  • Copy file if is greater:
@echo off 

set "_bit=is greater"
setlocal enabledelayedexpansion
   
for %%i in ("*.zip")do if %%~zi gtr 1000 (
   copy /b "file" + "%%~fi" "%%~dpni_new%%~xi" 2>nul 
   echo\File %%~nxi ^| Size %%~zi !_bit! than 1000 ) else ( 
   echo\File %%~nxi ^| Size %%~zi !_bit: = NOT ! than 1000 )

endlocal && goto=:EOF
  • Copy file if is NOT greater:
@echo off

set "_bit=is greater"
setlocal enabledelayedexpansion

for %%i in ("*.zip")do if %%~zi leq 1000 (
   copy /b "file" + "%%~fi" "%%~dpni_new%%~xi" 2>nul 
   echo\File %%~nxi ^| Size %%~zi !_bit: = NOT ! than 1000
   ) else ;echo\File %%~nxi ^| Size %%~zi !_bit! than 1000

endlocal && goto=:EOF

For PowerShell

Get-Item "D:\Folder\*.zip"|foreach-object { if ($_.Length -gt 1000) 
  { Write-Host $_.Length is greater than 1000 } else { 
    Write-Host $_.Length is NOT greater than 1000 }}
  • Or, with aliases:
 gi "D:\Folder\*.zip" | ? { if ( $_.Length -gt 1000 ) 
  { write-host $_.Length is greater than 1000 } else { 
     write-host $_.Length is NOT greater than 1000 } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.