Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
Hi! I'm new here, so hopefully some1 can guide me in creating a batch (I'm using XP).
Here's the purpose:
1) I have a folder named "ABC".
2) I used a batch to call 7-Zip (7za.exe) to compress this folder with multiple compression methods (-mx1, ... -mx8, -mx9). Then I append this method into the output's file extension (.7z-mx1, ... .7z-mx8, .7z-mx9). The reason I'm doing this is to generate different outputs with different compression levels.Below is the working script:
for /D %%i in (ABC) do (
7za a -r -mx1 "%%~i.7z-mx1" "%%i"
[more lines here]
7za a -r -mx7 "%%~i.7z-mx7" "%%i"
7za a -r -mx8 "%%~i.7z-mx8" "%%i"
7za a -r -mx9 "%%~i.7z-mx9" "%%i"
)3) As per subject, I'd like to continue this script by doing a filesize comparison on all files (ABC.*) and keeping only the smallest (thus, deleting the largest).
If any of the smallest files has the exact same file size, then it will remain.
Any kind expert able to help?
Thanks!

@echo off
SetLocal EnableDelayedExpansionfor /L %%n in (1,1,9) do for /D %%i in (IndexChart) do (
7za a -r -mx%%n "%%~i.7z-mx%%n" "%%i" >nul
)for /f "tokens=* delims=" %%f in ('dir /b /o-d *.7z-mx?') do (
if not defined smallest set /a smallest=%%~zf
if %%~zf gtr !smallest! del %%f & echo deleted %%f size=%%~zf ^> !smallest!
)
ENDLOCAL

sory, wrong program flow. use this instead. it allows 7zipping multiple directory and check size for each 7z'ed directory. use * in for/d loop.
@echo off
SetLocal EnableDelayedExpansionfor /D %%i in (ABC) do (
for /L %%n in (1,1,9) do 7za a -r -mx%%n "%%~i.7z-mx%%n" "%%i" >nul
for /f "tokens=* delims=" %%f in ('dir /b /o-d %%~i.7z-mx?') do (
if not defined smallest set /a smallest=%%~zf
if %%~zf gtr !smallest! del %%f & echo deleted %%f size=%%~zf ^> !smallest!
)
)
ENDLOCAL

hi reno,
much appreciate your solutions...
however, it doesn't always work if i have multiple folders ...
first 1st folder usually it's ok (smallest file remains) .. but the 2nd-nth folders are not parsed ...

hi reno,
it's almost working, except the following that I encountered:
Size 60651 for ABC.7z-mx9
Size 60268 for ABC.7z-mx8
Size 60268 for ABC.7z-mx7
Size 60697 for ABC.7z-mx6
Smallest found 60651
Deleted "ABC.7z-mx6" size=60697 > 60651Above is the output which I echo-ed it out to determine the problem.
Isn't this strange that mx8/mx9 file are not considered small and its value not loaded into the smallest variable?

ok, i found out what the problem.
ur script is based on the assumption that mx9 file will be the smallest, thus its size will be loaded into 'smallest' variable. the rest of the files are just compared to this variable and if greater, then it'll be deleted.
however, it doesn't take care the logic whatif mx8/mx7 is smaller than mx9?
in short, all the files are not compared to each other, only then the smallest value to be loaded into the variable.

ok, found out that it's not the comparison logic, but the DIR sorting output. the script sorted the output based on date (latest).
here's a fix for the script...
dir /b /os will sort the dir output smallest first, thus this smallest value will be loaded into the variable.
@echo off
SetLocal EnableDelayedExpansionfor /D %%i in (ABC) do (
for /L %%n in (1,1,9) do 7za a -r -mx%%n "%%~i.7z-mx%%n" "%%i" >nul
for /f "tokens=* delims=" %%f in ('dir /b /os %%~i.7z-mx?') do (
if not defined smallest set /a smallest=%%~zf
if %%~zf gtr !smallest! del %%f & echo deleted %%f size=%%~zf ^> !smallest!
)
set smallest=
)
ENDLOCALfinally! all works fine now!
BIG THANKS TO YOU, RENO! ;)

well, I think you do not need to compare and find the smallest.....
for /f "tokens=* delims=" %%f in ('dir /b /o-s %%~i.7z-mx?') do set SmallestFile=%%f
: - will get us the smallest.
: then,
ren %smallestfile% different-sounding-name
:del all other files using wild card.--
Holla.

hi Holla,
1) Isn't /o-s reverse the dir output from largest to smallest? How is the smallest gets loaded into SmallestFile variable then?
2) Personally, I like reno's script because this line ->
if %%~zf gtr !smallest! del %%f & echo deleted %%f size=%%~zf ^> !smallest!
echoes me which file is deleted, its size compared to the !smallest! value (by getting the 1st smallest file sorted via dir /os)
this echo saves my time instead of checking each file to find out which is the smallest :)
thanks guys for all the your great help :)

More simply:
=================================
@echo off & setLocal EnableDelayedExpansionfor /f "tokens=* skip=1 delims= " %%a in ('dir/b/a-d/os') do (
echo del %%a
)
=====================================
If at first you don't succeed, you're about average.M2

original post by cybpsych:
"If any of the smallest files has the exact same file size, then it will remain."thats why there is a need for size comparison. or another alternative can use neq.
if %%~zf neq !smallest! del %%f

Multiple smallest is a cotradiction in terms.
Either it's the smallest or it isn't.
=====================================
If at first you don't succeed, you're about average.M2

It is possible to "hybridise" the compression and M2's scripts without the chance of deleting any other files that may be in the directory, but as reno points out if two files are the same size only one of them will be kept, probably the the lowest number of compression i.e. mx1. I also reduced you compression commands but using for /l.
for /D %%i in (abc) do (
for /l %%c in (1,1,9) do (
7za a -r -mx%%c "%%~i.7z-mx%%c" "%%i"
)
for /f "skip=1 delims=" %%a in ('dir/b/a-d/os "%%~i.7z-mx9" "%%~i.7z-mx8" "%%~i.7z-mx7" "%%~i.7z-mx6" "%%~i.7z-mx5" "%%~i.7z-mx4" "%%~i.7z-mx3" "%%~i.7z-mx2" "%%~i.7z-mx1"') do echo del "%%a"
)

cybpsych,
I owe you an explanation for this:
hi Holla,
1) Isn't /o-s reverse the dir output from largest to smallest? How is the smallest gets loaded into SmallestFile variable then?
for /f "tokens=* delims=" %%f in ('dir /b /o-s %%~i.7z-mx?') do set SmallestFile=%%f
Executes the same command "set SmallestFile=%%f " sequentially for every file in the directory, starting from largest to smallest.
So after assigning all files, at the end of the for loop, the smallest stays as the value of the variable. Hope I have explained properly.As for the solution to your problem,
1. As reno said, the above statement will get you only the last file. If there are more than one file with the same size, you will get only one file.2. Now since M2 has spoken, there can not be any better optimized, shorter solution :-)
--
Holla.

hi holla, now i understand.
in ur first post, after this FOR line, next would be
ren %smallestfile% abcdef.7z
this line gives me an error: "The syntax of the command is incorrect"
also, shouldn't del comes before ren? reason is that if ren comes first, then the 2nd var entry will be renamed as the first, thus filaname collision occurs.

Please use M2's or Judago's solution.
Why waste time on analysing something
suboptimal...--
Holla.

Why all this nitpicking? Depending on the final file sizes, all the files may occupy the same space if they contain the same number of clusters. Unless the all files (in a directory or partition) are concatinated (sp?) it appears all the methods in the example will take the same amount of disk space.

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |