anve
Goto Top

Kompressionsrate berechnen

Zwei Dateien sollten anhand ihrer Dateigröße so verglichen werden, dass damit die Kompressionsrate ausgerechnet werden kann. Die Kompressionsrate gibt das Verhältnis von komprimierter und ursprünglicher Datei an.

Hallo zusammen!

Wie kann ich die Kompressionsrate ausrechnen? Ich weiß wie ich die Dateigröße herausbekomme und ausgeben kann. Wie mache ich das jetzt aber alles in einer Ausgabezeile? Eine FOR- in einer FOR-Schleife (geschachtelt) macht ja nicht das richtige, da alle Dateien dann ausgegeben werden. Zwei "Parameter" in einer FOR-Schleife gehen auch nicht, oder?

Hier mal mein Code:

@echo off

REM Kompressionsrate berechnen

echo ////////////////////////////////
set "tab=        "  
set origpath=C:\temp\test\*.bmp
set comppath=C:\temp\test\*.zip
echo Ursprungsdateien: %origpath%
echo Komprimierte Datein: %comppath%
echo.
echo Datei %tab% Urspr. Groesse %tab% Kompr. Groesse %tab% k-Faktor
for /f "delims=" %%i in ('dir /b /s "%origpath%"') do (  
	Echo %%~nixi %tab% %%~zi
	
)
echo ////////////////////////////////

Also es soll folgendes können:
-Kompressionsrate pro Datei
-durchschnittliche Kompressionsrate am Ende

Zu "Kompressionsrate pro Datei":
Wie setze ich zwei Dateien ins Verhältnis? Also bball.bmp & bball.zip?

Zu "durchschnittliche Kompressionsrate am Ende":
Theoretisch müsste ich zwei Variablen mitführen. Eine als Summe und die andere als Anzahl. Am Ende mache ich dann eine Division und gebe das Ergebnis aus.

[EDIT]
Hier mein erster Ansatz mit oben genannten Problem, dass ich keine zwei IN darin haben darf bzw. %%i und %%j:
@echo off

set path=C:\temp\
set origpath=C:\temp\test\*.bmp
set comppath=C:\temp\test\*.zip

if EXIST "%path%orig.txt" del "%path%orig.txt"  
if EXIST "%path%comp.txt" del "%path%comp.txt"  
for /f "delims=" %%i in ('dir /b /s "%origpath%"') do (  
	Echo %%~zi>>orig.txt	
)
for /f "delims=" %%i in ('dir /b /s "%comppath%"') do (  
	Echo %%~zi>>comp.txt	
)

set sum=0
set anz=0
for /f "delims=" %%i %%j in ("%path%orig.txt") in ("%path%comp.txt") do (  
	set orig=%%~zi;
	set comp=%%~zj;
	set /a erg=comp/orig
	echo K-Faktor %erg% %
	set /a sum=sum+erg
	set /a anz+=1
)
set /a avg=sum/anz
echo Durchschnitt: %avg%
[/EDIT]

Ich würde mich auf eine Hilftestellung freuen!

LG
anve

Content-Key: 102749

Url: https://administrator.de/contentid/102749

Printed on: April 16, 2024 at 23:04 o'clock

Member: Ren
Ren Nov 26, 2008 at 17:51:18 (UTC)
Goto Top
Skizze:
@echo off

REM Kompressionsrate berechnen

echo ////////////////////////////////
set "tab=        "  
set origpath=C:\temp\test\*.bmp 
set comppath=C:\temp\test\*.zip
set "compPathFile=C:\temp\test"  
echo Ursprungsdateien: %origpath%
echo Komprimierte Datein: %comppath%
echo.
echo Datei %tab% Urspr. Groesse %tab% Kompr. Groesse %tab% k-Faktor
for /f "delims=" %%i in ('dir /b /s "%origpath%"') do (  
    for /f "delims=" %%j in ('dir /b /s "%comppath%\%%~ni.zip"') do (  
	set "file=%%~ni%%~xi"  
	set /a orgsize=%%~zi
	set /a comsize=%%~zj
	set /a kfac=%%~zi*100/%%~zj
	)
	call :ausgabe
)
echo ////////////////////////////////
goto :eof
:ausgabe
Echo %file% %tab% %orgsize% %tab% %comsize% %tab% 100: %kfac%
goto :eof
Den Faktor 100 habe ich eingebaut, weil man meines Wissens mit Batch nichts so leicht mit Kommas rechnen kann. Wenn du also 1:kfac haben willst, dann musst du die Zahlen noch durch 100 teilen. Das sollte aber kein Problem sein.
Member: miniversum
miniversum Nov 26, 2008 at 17:52:47 (UTC)
Goto Top
Ich gehe mal davon aus das es für jede orginal bmp Datei eine zip Datei im gleichen Verzeichnis mit dem gleichen Namen gibt (ungetestet):
@echo off
REM Kompressionsrate berechnen

echo ////////////////////////////////
set "tab=        "  
set origpath=C:\temp\test\*.bmp
set comppath=C:\temp\test\*.zip
echo Ursprungsdateien: %origpath%
echo Komprimierte Datein: %comppath%
echo.
echo Datei %tab% Urspr. Groesse %tab% Kompr. Groesse %tab% k-Faktor
set anzahl=0
set rate=0
set rateall=0
for /f "delims=" %%i in ('dir /b /s "%origpath%"') do (  
for /f "tokens=3 delims= " %%a in ('dir /-c "%%~ni.bmp"^|find "%%~ni.bmp"') do set orgsize=%%a  
for /f "tokens=3 delims= " %%a in ('dir /-c "%%~ni.zip"^|find "%%~ni.zip"') do set kompsize=%%a  
call verarbeite "%%~ni" %orgsize% %kompsize%  
)
set /a rate=%rateall%/%anzahl%
echo durchschnittliche Kompressionsrate: %rate%
echo ////////////////////////////////
goto:eof

:verarbeite
set /a anzahl=%anzahl%+1
set /a rate=%orgsizeall%/%kompsizeall%
set /a rateall=%rateall%+%rate%
echo %1: %tab% %2 %rate%

Du könntest allerdings Probleme mit nachkommastellen bekommen.
Member: anve
anve Nov 26, 2008 at 18:31:49 (UTC)
Goto Top
Hallo Ren!

Vielen Dank für deine Hilfe!

Was ich nicht verstehe ist wie die geschachtelte FOR-Schleife funktioniert. Müsste die nicht die Operation mehrfach durchführen (je nachdem wieviele Files vorhanden sind)?

Zeile 15 habe ich angepasst:
for /f "delims=" %%j in ('dir /b /s "%compPathFile%\%%~ni.zip"') do (  

Wenn ich das Ergebnis durch 100 teile, wird ja der Nachkommabereich abgeschnitten. Gibt es da ein Workaround? Von meinem letzten Thread hab ich das hier erhalten:

set /a s=Dauer / 100
set /a c=100 + Dauer %% 100
echo Gesamtdauer in Sekunden: %s%,%c:~-2%

Dabei verstehe ich die zweite Zeile nicht so ganz. Da wird Hundert dazu gezählt. Was macht %% 100?
Zum Schluss wird der Vorkommateil, der Beistrich und der Nachkommateil ausgegeben. Das müsste auch so ähnlich funktionieren...

LG
anve
Member: anve
anve Nov 26, 2008 at 18:32:42 (UTC)
Goto Top
Hi miniversum!

Toll, wie immer gleich zwei Auswahlmöglichkeiten hier! face-smile

Leider findet er bei mir das find nicht:
Der Befehl "find" ist entweder falsch geschrieben oder konnte nicht gefunden werden.

[EDIT]
Ich arbeite hier auf einem Rechner mit eingeschränkten Rechten. Oder kann es sein, dass eine Registrierung durchgeführt werden muss? Ala
regsvr32 zipfldr.dll
[/EDIT]

Wie könnten die for-Schleifen aussehen, wenn zwei unterschiedliche Verzeichnisse verwendet würden (gleiche Namen gewährleistet, nur unterschiedliche Dateiendungen)? Aber da es ja schon eine Lösung gibt, musst du diese Frage nicht unbedingt beantworten ... Mit den Nachkommastellen hast du allerdings Recht.

BTW:
Von meinem vorigen Thread funktioniert alles wunderbar, nur ich bekomme ständig folgende Fehlermeldung:
Das System kann das angegebene Laufwerk nicht finden.

Gibts etwas was ich dagegen tun kann? Ich hab Ausgaben die ich machen will und die obige wieder nicht.

Hast du eine Ahnung was falsch sein könnte?

LG
anve
Member: Ren
Ren Nov 26, 2008 at 18:44:16 (UTC)
Goto Top
Die zwei For-Schleifen sind eigentlich gar keine. Er sucht sich die zip-Datei, mit dem gleichen Namen, wie die Ursprungsdatei. Davon gibt es nur eine. Das nutze ich nur, damit ich von der Zip-Datei auch die Größe bekomme. Das geht vielleicht auch eleganter, kA.
Die zweite Zeile scheint für mich der Modulo-Operator zu sein. Damit bekommst du den Rest der Division von Dauer durch 100. So ergibt es aber für mich gerade keinen Sinn:
set /a vorkomma=%size%/100
set /a nachkomma=%size% %% 100
echo Größe: %vorkomma%,%nachkomma%
Member: anve
anve Nov 26, 2008 at 19:05:59 (UTC)
Goto Top
Ach, jetzt seh ich es. Für jedes ZIP-File machst du das. Das ~ni hab ich nicht bedacht.

Modulo macht Sinn. Ich hab es eingebaut und es funktioniert soweit. Ich verstehe es so:
-Division durch 100 ergibt den Vorkommaanteil
-Modulo Operation ergibt den Rest also den Nachkommaanteil.

Die Frage ist wie man die Genauigkeit erhöhen kann. Also z.B. Promille-Bereich
Member: Ren
Ren Nov 26, 2008 at 19:29:55 (UTC)
Goto Top
Mit dem Modulo musst du aufpassen: Modulo ist der Rest: Beispiel: 9 mod 4 = 1. 9 / 4 ist aber nicht 2,1, sondern 2,25. Im Prinzip ist es sowas: 9 / 4 = 2 + 1 / 4, wobei die 1 der Modulo-Wert ist. Die Genauigkeit kannst du nicht großartig beeinflussen, das liegt am begrenzten Wertebereich.
Member: anve
anve Nov 26, 2008, updated at Oct 18, 2012 at 16:36:36 (UTC)
Goto Top
Stimmt! Hmm, gibt es keinen Datentyp der die Nachkommastellen behält? Wahrscheinlich kann man nur den Weg mit der Überführung in eine große Zahl nehmen.

Hier ist nochmal der Weg mit dem Modulo erklärt: Zeit messen für das Erstellen einer RAR-Datei

Zitat von @bastla:
Um den Nachkommaanteil in der letzten Zeile zweistellig
ausgeben zu können, wird dieser wiederum durch Hinzufügen
von 100 in den dreistelligen Bereich gebracht und durch Bildung des
Teilstrings "letzte 2 Zeichen" bei Bedarf mit führender
Null erzeugt.

Aber das wird auch nicht weiter helfen ...

Gibt es eigentlich eine Lösung für die Anpassung der Tabs?
Member: Ren
Ren Nov 26, 2008, updated at Oct 18, 2012 at 16:36:36 (UTC)
Goto Top
Natürlich gibt es einen Möglichkeit, aber das wird aufwändig: Hier kannst du mal gucken, wie man die Länge einer Variable bekommst:
suche sowas wie get.length um eine bestimmte zeilenlaenge einer Batch-Datei auszulesen...
wenn du die hast, dann kannst du die Tabs durch eine errechnete Anzahl an Leertasten ersetzten. Das geht, aber für mich würde es den Aufwand und die Performance nicht aufwiegen, dann habe ich es lieber hässlich.
Member: anve
anve Nov 26, 2008 at 22:37:23 (UTC)
Goto Top
Hallo Ren!

Ja, das ist zu aufwändig! Das kann man machen wenn man zuviel Zeit hat ;)
Vielen Dank für deine Mithilfe!

Hast du eine Ahnung was folgende Fehlermeldung bedeutet:
Das System kann das angegebene Laufwerk nicht finden.

LG
anve
Member: bastla
bastla Nov 26, 2008 at 23:07:11 (UTC)
Goto Top
Hallo anve und Ren!

Eine zwar nicht optimale, aber vielleicht doch akzeptable Lösung für die übersichtliche(re) Ausgabe könnte darin bestehen, manuell eine ausreichende Anzahl von Leerzeichen anzufügen und dann die gewünschten Teile mit einer fixen Spaltenbreite "abzuschneiden" - für den Dateinamen etwa:
set "file=%%~nxi                              "
Bei der Ausgabe dann einfach
echo %file:~,30%
Analog für die Größenangaben (da ohnehin nicht mit den Variablen gerechnet wird, können diese ohne "/a", aber mit einigen Leerzeichen festgelegt werden):
set "orgsize=         %%~zi"
Ausgabe mit 9 Stellen (rechtsbündig):
echo %orgsize:~-9%
Grüße
bastla
Member: Ren
Ren Nov 27, 2008 at 13:36:04 (UTC)
Goto Top
wer oder was schmeißt denn diese Fehlermeldung?
Member: anve
anve Nov 27, 2008 at 17:26:14 (UTC)
Goto Top
Ich logge die Ausgabe ja mit. Die Fehlermeldung wird dabei in der Eingabeaufforderung ausgegeben. Ich bin draufgekommen, dass es nicht egal ist, wann ich Kommentare setze. Bsp.:

:: tu dies
command
:: tu das

Bei manchen Konstellationen kommt diese Fehlermeldung. Wie setze ich Kommentare richtig? Was ich bis jetzt weiß geht das mit REM und ::
Member: anve
anve Nov 27, 2008 at 17:28:57 (UTC)
Goto Top
Hi bastla!

Vielen Dank für den Tip! Diese Lösung sieht einfach aus. Dennoch werde ich jetzt die Ausgaben in eine csv-Datei speichern da ich dann keine Probleme mit dem Rechnen und insbesondere den Nachkommastellen mehr habe (mache die Rechnungen dann manuell). Das ist für mich im Moment die beste Lösung. Dann ran an die Arbeit ;)

LG
anve
Member: Ren
Ren Nov 27, 2008 at 21:19:17 (UTC)
Goto Top
Hm, sollte eigentlich egal sein. Offiziell sind Kommentare in Batch Zeilen hinter einem REM. Mit :: nutzt man aus, dass :: Text einen fehlerhafte Sprungzieladresse ist. Das wirkt dann sozusagen als Kommentar. Der einzige mir bekannte Unterschied ist, dass man, wenn man echo on schaltet, die Rem-Zeilen ausgegeben bekommt, während die :: nicht angesprungen werden, also auch nicht erscheinen.
Dass er find bei dir nicht findet, finde ich auch suspekt. Find ist ein externe Befehl, die Datei sollte in %windir%\system32\find.exe zu finden sein, und das sollte im Pfad sein. Wenn nicht, ist in meinen Augen etwas nicht in Ordnung, es sei denn, unter Windows Vista oder seven oder weiß der Geier hat man find.exe weggelassen.
Member: anve
anve Nov 30, 2008 at 15:33:33 (UTC)
Goto Top
Ich werde ganz einfach den Fehler sein lassen so wie er ist. Er wird ja nur angezeigt und funktionieren tut das Skript trotzdem. Es hängt irgendwie mit der Auskommentierung und meinen verwendeten Codezeilen zusammen.

Find wurde auf einem anderen Rechner jetzt gefunden. Dort habe ich Admin-Rechte und da geht es. Beim vorherigen Rechner hatte ich keine Admin-Rechte, aber ich werde mal die find.exe dort suchen. Wie schon gesagt, ich vermute:

a) find.exe nicht vorhanden (was ich mir nicht so ganz vorstellen kann)
b) Registrierung

Z.B. hat dort der Windows-Interne Befehl ZIP auch nicht funktioniert. Und diese Zip-Funktionalität kann man aktivieren und deaktivieren. In meinem Fall hat das auch nichts geholfen. Jedenfalls kann ich nicht über die Konfiguration des Rechners bestimmen. Komischerweise ist der zip-Befehl auf einem anderen Rechner (auch mit eingeschränkten Admin-Rechten) gegangen. Ich werde einfach den Rechner wechseln ...

Vielen, vielen Dank an euch beiden! Ihr habt mir sehr geholfen! Echt großartige Unterstützung von euch!

LG
anve