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
    )
    )
6
  • 1
    technically, because %filesize% is not defined, so the if syntax is invalid. You'd need delayed expansion
    – Stephan
    Jul 27, 2020 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. Jul 27, 2020 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, 2020 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" Jul 28, 2020 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, 2020 at 18:44

2 Answers 2

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
    )
)
7
  • @peterboston check the snippets now
    – Wasif
    Jul 26, 2020 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. Jul 26, 2020 at 16:29
  • 1
    with another forloop: for %%j in ("%%~ni-new") do set "newsize=%%~zj"
    – Stephan
    Jul 27, 2020 at 16:56
  • 1
    Thanks @Stephan for the note.
    – Wasif
    Jul 28, 2020 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 Jul 28, 2020 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 } }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .