cced-de
Goto Top

Verzeichnissgröße per Batch vergleichen.

Hallo zusammen,
ich möchte die Größe eines Verzeichnisses auslesen, danach soll geprüft werden, ob der Inhalt des Verzeichnisses 4 GB überschreitet.
Ist dies der Fall, soll ein Archiv aus dem Verzeichniss mittels 7Zip erstellt werden und mehrere Volumes daraus erstellt werden.
Ist der Verzeichnissinhalt kleiner als 4 GB, soll nur ein gewöhnliches Archiv ohne Volumes erstellt werden.

Hier mein Ansatz:

Set PackFile=%startdir%%ordner%
	IF /i [%2]==[/R] for /R "%~1" %%a in (.) do @%0 "%%a" %3  
	if not [%2]== Set /a "Level=%2+2"  
	if defined level for /f "delims=\ tokens=1,%level%" %%i in ("%~1") do if not [%%j]== goto :eof  
	If exist "%PackFile%" (     
	  for /f "tokens=3" %%c in ('dir "%PackFile%" /s ^2^>nul^| findstr /c:"Datei(en)" ') do set DirSize=%%c  
	)
	set "space20=                 "  
	if defined DirSize set "Dirsize=%space20%%Dirsize%"  
	if defined DirSize echo %DirSize:~-15%    %~f1
	
	if %DirSize:~-15% GTR 4.294.967.296 goto Packe4GB
	if %DirSize:~-15% LEQ 4.294.967.296 goto PackeNormal 
	
	:Packe4GB
	"%ProgramFiles%\7-Zip\7z.exe" a -v4g -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r "%Ordner%.zip"   
	goto PackEnd
	
	:PackeNormal
	echo kleiner oder gleich 4 GB
	"%ProgramFiles%\7-Zip\7z.exe" a -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r "%Ordner%.zip"   
	echo ! - %Date% - %Time%: %Ordner%.zip erstellt.>>%SLOG%
	:PackEnd

Ich denke mein Problem liegt bei Zeile 12 + 13.
Wenn ich so ein Verzeichnis mit z.B. 98.769.255 MB Prüfen lasse, geht das Script davon aus, dass es größer als 4 GB ist.
Ich denke mal es liegt an den Dezimalstellen.

Hat da vielleicht jemand eine Lösung für mich?
Gruß CCED

Content-Key: 168274

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

Ausgedruckt am: 29.03.2024 um 09:03 Uhr

Mitglied: Friemler
Friemler 19.06.2011 um 21:25:56 Uhr
Goto Top
Hallo CCED,

zur Bestimmung der Größe aller Dateien im übergebenen Verzeichnis und darunterliegenden Verzeichnissen würde ich folgendes verwenden:
set "SrcDir=%~1"  

for /f "tokens=3" %%s in ('dir /s /-c "%SrcDir%" ^| find "Datei(en)"') do (  
  set Size=%%s
)

Dann brauchst Du das Batchscript nicht rekursiv starten, was ohne ein CALL vor dem @%0 in Zeile 2 ja sowieso nicht funktioniert hätte. face-wink

Wegen dem Parameter /s durchläuft der DIR-Befehl das übergebene und alle darunterliegenden Verzeichnisse und zeigt wegen /-c in der Zusammenfassung die Gesamtgröße aller Dateien ohne Tausendertrennzeichen an. DIR /S gibt einmal nach jedem Verzeichnis die Größe aller darin enthaltenen Dateien aus und zum Schluss die Größe aller angezeigten Dateien. Alle diese Zeilen enthalten den String "Datei(en)" und werden von FIND deshalb gefunden, der letzte Fund ist der richtige.

Gruß
Friemler


[EDIT]
HALT, STOP!! face-wink
Mit Variablen in Batchscript kann nur bis +2147483648=2^31 gerechnet werden! Du musst Deine Grenzen anders setzen, 4GB sind zu groß.
[/EDIT]
Mitglied: pieh-ejdsch
pieh-ejdsch 19.06.2011 um 21:51:02 Uhr
Goto Top
moin cced-de,

die CMD rechnet nur bis knapp 2 Giga so wie sie soll.
und wenn die Linke Seite Größer als 999999 ist Rechnet es auch immer richtig.
entweder Du Rechnest das zusammen wie hier Inhalt Verschieben zum sichern auf Externe Medien nach Dateianzahl bzw Medium Groesse mit Logging in Ordner

oder Teilst Den Ausgabestring der Größe in zwei bestandteile

for /f "tokens=3" %%i in ('dir /s /-c^|findstr /c:" Datei(en),"^|findstr /e /c:" Bytes"') do set "DirSize=%%i"  

if %DirSize% gtr 999999 (set "over=%DirSize:~0,-6%" && set "under=%DirSize:~6%") else goto :PackNormal  

if %over% equ 4294 if %under% gtr 967296 goto :Packe4GB
if %over% gtr 4294 goto :Packe4GB


[Edit] etwas zu spät und noch eine Option /s speniert [7eDIT]
Gruß Phil
Mitglied: cced-de
cced-de 19.06.2011 um 22:30:51 Uhr
Goto Top
Zitat von @Friemler:
[EDIT]
Mit Variablen in Batchscript kann nur bis +2147483648=2^31 gerechnet werden! Du musst Deine Grenzen anders setzen, 4GB sind zu
groß.
[/EDIT]

Hallo Friemler,
hmmm naja, in manchen Verzeichnissen liegen nun mal mehr als 4 GB..
Es gibt doch sicher die Möglichkeit die Ergebniszahl aus meinem Script z.B. 85.477.161.058 (85 GB)
in eine z. B. zweistellige Zahl (85) umzuwandeln... und dann diese einfach mit dem angegebenen Wert 4
zu "vergleichen"... Also
if %DirSize:~-15% GTR 4 goto Packe4GB 
oder ?
Gruß CCED
Mitglied: cced-de
cced-de 19.06.2011 um 22:36:05 Uhr
Goto Top
Hallo Phil,

auch dir danke für deine Mühe.
Ich habe deinen Ansatz mal ein wenig verändert:
Set PackFile=%startdir%%ordner%

	for /f "tokens=3" %%i in ('dir %PackFile% /s /-c^|findstr /c:" Datei(en),"^|findstr /e /c:" Bytes"') do set "DirSize=%%i"  
			 
	if %DirSize% gtr 999999 (set "over=%DirSize:~0,-6%" && set "under==%DirSize:~6%") else goto :PackeNormal  
	if %over% equ 4294 if %under% gtr 967296 goto :Packe4GB
	if %over% gtr 4294 goto :Packe4GB

aber auch so glaubt cmd immer der Wert sei größer als 4294.
face-sad

Gruß CCED
Mitglied: Friemler
Friemler 19.06.2011 um 22:58:36 Uhr
Goto Top
Das Problem ist, dass Du mit dem Wert der Variablen Size aus meinem Skript nicht rechnen und auch keine Vergleiche durchführen kannst. Bei einem GTR oder LSS usw. wird intern auch gerechnet. Wenn der Wert von Size dann gößer 2^31 - 1 ist (die größtmögliche positive Zahl), kommt wieder Mist dabei heraus.

Ich habe die Tage in irgendeinem Batchforum einen Beitrag zum Thema gesehen, ich schau mal nach, ob ich den nochmal finde. In dem Beitrag ging es um das Rechnen mit noch viel größeren Zahlen.

Gruß
Friemler
Mitglied: pieh-ejdsch
pieh-ejdsch 19.06.2011 um 23:04:31 Uhr
Goto Top
in Zeile 05 ist ein = beim SET zuviel. Das hatte ich schon weg-editiert. Du hast dieses aber noch mit drinnen. Probier es nochmal.

Gruß Phil
Mitglied: cced-de
cced-de 19.06.2011 um 23:25:31 Uhr
Goto Top
Hi Phil...
the same face-sad

habe das = mal rausgenommen, funktioniert aber nicht!
So siehst jetzt aus...

 	Set PackFile="Y:\TestOrdner"  
	for /f "tokens=3" %%i in ('dir "%PackFile%" /s /-c^|findstr /c:" Datei(en),"^|findstr /e /c:" Bytes"') do set "DirSize=%%i"  
			 
	if %DirSize% gtr 999999 (set "over=%DirSize:~0,-6%" && set "under=%DirSize:~6%") else goto :PackeNormal  
	if %over% equ 4294 if %under% gtr 967296 goto :Packe4GB
	if %over% gtr 4294 goto :Packe4GB

	:Packe4GB
	echo Packe Groesser als 4 GB

	"%ProgramFiles%\7-Zip\7z.exe" a -v4g -pDasPasswort -tzip -mx0 -r "%Ordner%.zip"   
	echo 1>%Startdir%%Ordner%\!Erledigt.DoNot.!UT

	goto PackEnd
	
	:PackeNormal
	echo Packekleiner oder gleich 4 GB


	"%ProgramFiles%\7-Zip\7z.exe" a -pDasPasswort -tzip -mx0 -r "%Ordner%.zip"   
	goto PackEnd

Gruß CCED
Mitglied: bastla
bastla 19.06.2011 um 23:45:54 Uhr
Goto Top
Hallo cced-de!

Es wundert mich, dass es mit dem Komma in der Zeile 2 überhaupt funktioniert hätte - versuch es einmal mit
for /f "tokens=3" %%i in ('dir "%PackFile%" /s /-c^|findstr /c:" Datei(en)"^|findstr /e /c:" Bytes"') do set "DirSize=%%i"
Ansonsten solltest Du mit einem
goto :PackeNormal
als (zusätzliche) Zeile 7 bessere Chancen haben ... face-wink

Grüße
bastla
Mitglied: Friemler
Friemler 19.06.2011 um 23:48:03 Uhr
Goto Top
Hallo CCED,

ich habe das Script gefunden. Es stammt von hier. In dem dort erhältlichen ZIP-File sind noch andere mathematische Unterprogramme zum Verrechnen von großen Zahlen enthalten (addieren, multiplizieren).

Ich habe Deinen und meinen Code mit dem von mir angepassten Script verschmolzen. Die Copyright-Klausel des Autors ist enthalten.

@echo off

setlocal


set "SrcDir=%~1"  

for /f "tokens=3" %%s in ('dir /s /-c "%SrcDir%" ^| find "Datei(en)"') do (  
  set "Size=%%s"  
)


call :IsLarger %Size% 4294967296

if %ERRORLEVEL% equ 1 goto :Packe4GB
goto :PackeNormal


:Packe4GB
"%ProgramFiles%\7-Zip\7z.exe" a -v4g -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r "%SrcDir%.zip"  
goto :PackEnd


:PackeNormal
"%ProgramFiles%\7-Zip\7z.exe" a -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r "%SrcDir%.zip"  


:PackEnd
echo ! - %Date% - %Time%: %SrcDir%.zip erstellt.>>%SLOG%

exit /b



:IsLarger
setlocal enabledelayedexpansion
  ::DETERMINE IF FIRST VAR IS LARGER THAN SECOND
  ::NUMBERS OF UP TO ~4000 DIGITS CAN BE COMPARED, NO MORE THAN ~8100 DIGITS COMBINED
  ::SYNTAX: CALL ISLARGER %_VAR1% %_VAR2%
  ::hieyeque1@gmail.com - drop me a note telling me
  ::if this has helped you.  Sometimes I don't know if anyone uses my stuff 
  ::Its free for the world to use.
  ::I retain the rights to it though, you may not copyright this
  ::to prevent others from using it, you may however copyright works
  ::as a whole that use this code.
  ::Just don't try to stop others from using this through some legal means. 
  ::CopyRight Brian Williams 5/18/2009
  :: %_VAR1% = VARIABLE AGAINST WHICH WE SHALL COMPARE
  :: %_VAR2% = VARIABLE TO BE COMPARED

  ::Rückgabewert  0 -> _Var1 = _Var2
  ::Rückgabewert  1 -> _Var1 > _Var2
  ::Rückgabewert -1 -> _Var1 < _Var2

  SET _NUM1=%1
  SET _NUM2=%2

  FOR /L %%A IN (1,1,2) DO (
    FOR /L %%B IN (0,1,9) DO (
      SET _NUM%%A=!_NUM%%A:%%B=%%B !
    )
  )

  FOR %%A IN (!_NUM1!) DO SET /A _NUM1CNT+=1 & SET _!_NUM1CNT!_NUM1=%%A
  FOR %%A IN (!_NUM2!) DO SET /A _NUM2CNT+=1 & SET _!_NUM2CNT!_NUM2=%%A

  IF !_NUM1CNT! NEQ !_NUM2CNT! (
    IF !_NUM1CNT! GTR !_NUM2CNT! (
      EXIT /B 1
    ) ELSE (
      EXIT /B -1
    )
  )

  FOR /L %%A IN (1,1,!_NUM1CNT!) DO (
    IF !_%%A_NUM1! NEQ !_%%A_NUM2! (
      IF !_%%A_NUM1! GTR !_%%A_NUM2! (
        EXIT /B 1
      ) ELSE (
        EXIT /B -1
      )
    )
  )

EXIT /B 0

Gruß
Friemler


[EDIT]
Die Methode zur Ermittelung der Gesamtdateigröße von pieh-ejdsch ist sicherer.
[/EDIT]
Mitglied: pieh-ejdsch
pieh-ejdsch 20.06.2011 um 00:27:26 Uhr
Goto Top
und zu dem von bastla als Zusatz in der Zeile 05. 2 einsen sponsoren
if %over% equ 4294 if 1%under% gtr 1967296 goto :Packe4GB
Dann klappts auch mit den Vornullen.

Gruß Phil
Mitglied: ovu-p86
ovu-p86 20.06.2011 um 00:32:46 Uhr
Goto Top
Hallo cced-de,

hier noch mal eine einfache Lösung.

Das Problem bisher lag, glaub ich, daran, daß die Auswertungen sich immer auf zu gr. Zahlen bezogen haben
(32-bit-Problem). Der kleine Zwischenschritt in Zeile 4 des cmd löst das Problem. Jetzt sind die Zahlen
handle, auswertbar.

Das "For" hab ich etwas geändert. Hab insbesondere auch hidden-, system- u.s.w Dateien mit einbezogen.
Wenn das nicht angegeben wird, ist das Ergebnis des "dir" verfälscht (System u. Hidden-Files fehlen dann
im Ergebnis).

echo off
Set PackFile=E:\test
for /f "tokens=3" %%i  in ('dir "%PackFile%" /s /w /-c /a: d r h a s ^| findstr /c:Datei^(en^) ') do set DirSize=%%i  
set DirSize=%DirSize:~0,-6%

if %DirSize% LEQ 4293 echo ++++++ %DirSize% ist kleiner Grenze ++++++
if %DirSize% GTR 4293 echo ++++++ %DirSize% ist groesser Grenze ++++++
pause

Den cmd kannst du ja zunächst mal ausprobieren.
Bei mir haut er hin.
Einfach das "Set PackFile" im Script mit deinen Verz. anpassen und testen.

Das "echo" kannst du dann ja später, wenns passt, beim Einbau in deinen Scipt mit deinen Befehlen ersetzen.


Gruß
Uwe

[EDIT]
hab die Größe auf 4293 statt 4294 gesetzt, da ja 6 Stellen in der Größe abgeschnitten werden.
Bei 4294 könnte ja durch die fehlenden 6 Stellen das Ganze doch größer als 4GB sein
[/EDIT]
Mitglied: cced-de
cced-de 20.06.2011 um 01:01:44 Uhr
Goto Top
Ihr seit die Größten hier !!!

Alle drei Lösungen funktionieren!!!
Danke für eure Zeit und eure Hilfe !!

Hier nochmal der zusammenhängende Code von Phil... so wie er funktioniert !

	Set PackFile="%startdir%%ordner%"  
	for /f "tokens=3" %%i in ('dir "%PackFile%" /s /-c^|findstr /c:" Datei(en)"^|findstr /e /c:" Bytes"') do set "DirSize=%%i"  
	if %DirSize% gtr 999999 (set "over=%DirSize:~0,-6%" && set "under=%DirSize:~6%") else goto :PackeNormal  
	if %over% equ 4294 if 1%under% gtr 1967296 goto :Packe4GB
	if %over% gtr 4294 goto :Packe4GB
        goto :PackeNormal
        
	:Packe4GB
	echo Packe Groesser als 4 GB
	"%ProgramFiles%\7-Zip\7z.exe" a -v4g -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r %Ordner%.zip  
	goto PackEnd
	
	:PackeNormal
	echo Packek leiner oder gleich 4 GB
	"%ProgramFiles%\7-Zip\7z.exe" a -p1.gEhEiMeSwOrT_$ -tzip -mx0 -r %Ordner%.zip   

	goto PackEnd

Nochmals meinen Dank!!

Gruß CCED (Markus)
Wird Zeit fürs Bett, um 05:00 Uhr ist die Nacht vorbei face-smile
Mitglied: ovu-p86
ovu-p86 20.06.2011 um 01:16:59 Uhr
Goto Top
Hallo cced-de,

eine Lösung reicht ja. Wenns funktioniert.

Aber würde dringend empfehlen beim "dir" noch "/a: d r h a s" anzufügen. (vielleicht etwas überkandidelt, aber unschädlich)
Wie gesagt, sonst ist das Ergebnis verfälscht. Hidden und System-Dateien werden im Ergebnis ohne das
nicht berücksichtigt.

Gruß
Uwe
Mitglied: Biber
Biber 20.06.2011 um 01:44:23 Uhr
Goto Top
Nich' hauen jezz', ovu-p86,

Zitat von @ovu-p86:
Aber würde dringend empfehlen beim "dir" noch "/a: d r h a s" anzufügen. (vielleicht etwas überkandidelt, aber unschädlich)
... in der Sache gebe ich dir (teilweise) recht - aber das Ergebnis "Alle Dateien mit welchem Attribut auch immer" bekommst du schneller mir "DIR /a *.*"

Und "teilweise" recht soll heissen..it depends....
Wenn CCED nur die Dateien packt, die sinnvoll sind, dann gehören z.B. hidden files wie desktop.ini's nicht dazu.
Und in seinem Fall scheint es, er wolle auch nur "Daten" sichern = alles Sichtbare,

Grüße
Biber
Mitglied: ovu-p86
ovu-p86 20.06.2011 um 02:08:27 Uhr
Goto Top
Hallo Biber,

warum?

Eher, danke für den Hinweis. Wußte gar nicht, daß nur "/a" identisch mit "/a: d r h a s" ist.
Spart mir doch Schreibarbeit.

Ansonsten;
Meines Wissens nach haut 7-zip alles, also auch hidden u. system, ins zip.
Deshalb gehe ich bzgl. des Ergebnisses lieber auf Nummer sicher.
(Obwohl das hier natürlich eher theoretisch ist, da das Ganze ja noch gezippt also verkleinert wird
und dadurch eh genug Spielraum für ein ungenaues Größenergebnis ist, ohne das es Auswirkungen
hat.. Kommt also auf ein Pfund mehr nicht an.)

Das "it depends. ..." trifft natürlich zu. Bsp. wäre wenn ich die Größe eines Verz. abfrage, um hinterher
z.B. mit xcopy was zu kopieren (wo ich hidden u. system nicht eingeschlossen habe)


Gruß
Uwe
Mitglied: bastla
bastla 20.06.2011 um 08:04:21 Uhr
Goto Top
@ovu-p86
... und wenn wir schon beim Thema sind:
dir /a-d
liefert alle Dateien ...

Grüße
bastla
Mitglied: pieh-ejdsch
pieh-ejdsch 20.06.2011 um 14:38:50 Uhr
Goto Top
moin,

da Friemler so einen Superschicken Code mit "nur zu verwenden mit Copyright Infos" hier hereingestellt hat (ich frag mich manchmal was bei ein bissel BatchZeilen geschütz werden muss???)

hier nochmal eine Absolut Free Variante davon:
:: use this Batch without Copyright info only 
@echo off
if "!os!" == "%OS%" (setlocal) else setlocal enabledelayedexpansion  
set "Erste=0%~1"  
set "Zweite=0%~2"  
set "mehr=dasselbe wie"  
for /f "Tokens=1,2 delims=:" %%a in ('  
^(
for %%i in ^("" %1 %2 ""^) do @echo\%%~i  
^)^|findstr /o "^"^|more +1  
') do (  
	if defined GrA set /a GrB = %%a - 3*Zuviel - GrA
	if defined Zuviel if not defined GrA set /a GrA = %%a - 2*Zuviel
	if not defined Zuviel set /a Zuviel = %%a
)
if %GrA% gtr %GrB% (set /a Max = GrA) else set /a Max = GrB
for /l %%i in (1,1,%Max%) do (
	for /f %%j in ("!Erste:~-%%i,1! 0") do for /f %%k in ("!Zweite:~-%%i,1! 0") do (  
		if %%j gtr %%k set "mehr=mehr als"  
		if %%j equ %%k set "mehr=!mehr!"  
		if %%j lss %%k set "mehr=weniger als"  
)	)
echo %1 ist %mehr% %2

Gruß Phil
Mitglied: Friemler
Friemler 20.06.2011 um 15:09:54 Uhr
Goto Top
Hallo pieh-ejdsch,

Zitat von @pieh-ejdsch:
ich frag mich manchmal was bei ein bissel BatchZeilen geschütz werden muss???

der Autor des Codes kommt sehr wahrscheinlich aus USA und dort gibt es Softwarepatente. Er schreibt in seiner Copyright-Klausel ja auch, dass der Code frei ist, dass aber niemand anderes diesen Code unter sein Copyright stellen darf und somit anderen die Benutzung verbieten kann. Wohl kann aber fremder Code, der diesen Code benutzt, unter ein Copyright gestellt werden. Ich habe das dringelassen, weil ich mich nicht mit fremden Federn schmücken möchte.

Gruß
Friemler
Mitglied: pieh-ejdsch
pieh-ejdsch 20.06.2011 um 15:37:09 Uhr
Goto Top
ach so is das gemeint - wer nicht Guttenbergen will soll die Quelle nicht Vergessen ... und den Doktor machen!

aber warum wird in diesem Code ein Errolevel 0 ausgeben wenn die Zahlen gleich sind?
Das Programm heist doch "isLarger" und nicht isEqual - naja das weiss nur der Brain äähhm ich meinte Brian.

Gruß Phil
Mitglied: Friemler
Friemler 20.06.2011 um 15:54:30 Uhr
Goto Top
Hey pieh-ejdsch,

das mit dem Errorlevel stammt von mir, das meinte ich u.a. mit Anpassungen. Ich habe mich bei den Codes (0, 1, -1) am Verhalten von vergleichbaren Funktionen in höheren Programmiersprachen orientiert.

Evtl. habe ich mit meinen Anpassungen aber auch die Funktion des Codes von Brian eingeschränkt. Er schreibt ja, dass damit zwei Zahlen von jeweils ca. 4000 Stellen verglichen werden können. Das könnte in meiner Version nicht mehr so sein, da das den internen Code zur Übergabe von Parametern überfordern könnte. Brian hat in seiner Originalversion die Namen von Variablen, die die zu vergleichenden Zahlen enthalten, übergeben, quasi ein "Call-By-Reference" in Batch. Damit wäre aber die Übergabe von Konstanten nicht möglich gewesen.

Schau Dir doch mal das Original an, wie gesagt, das ZIP-File enthält auch noch andere interessante Batch-Unterprogramme.

Gruß
Friemler