cmichel
Goto Top

Bedingung in Abhängigkeit vom Alter einer Datei

Hi @ all,

Ich hoffe jemand kann mir helfen:
Was ich brauche ist ein dos script, welches das alter einer bestimmten Datei abfragt
und dann in einer Bedingung auf eine bestimmte Position springt.

Wenn Datei älter als 30 min dann gehe dahin ansonsten gehe dorthin

Ich hoffe mal für die DOS Profis hier ist das eine 3min Sache ;)

MfG
Christof

Content-ID: 38713

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

Ausgedruckt am: 20.11.2024 um 15:11 Uhr

bastla
bastla 27.08.2006 um 20:26:22 Uhr
Goto Top
Hallo Christof!

Da ich kein DOS-Profi bin kann ich nur eine Lösung per VB-Script anbieten:

'Script ISOLD.vbs  

'Erwartete Argumente: Datei, Minuten  

'Rückgabe: errorlevel = 0 für Datei ist älter als "Minuten"  
'		  errorlevel = 1 für Datei existiert, ist aber nicht älter als "Minuten"  
'	  	errorlevel = 2 für Fehler; bei Bedarf kann weiter differenziert werden  
'				       (zB fehlende Argumente, Datei nicht gefunden, ... s. u.)  

Dim fso, f, mins
Set fso = CreateObject("Scripting.FileSystemObject")  
If WScript.Arguments.Count <> 2 Then
	WScript.Quit(2) 'zu wenig Argumente übergeben --> Rückgabe errorlevel 2  
Else
	f = WScript.Arguments(0)
	mins = CInt(WScript.Arguments(1))
End If

If Not fso.FileExists(f) Then WScript.Quit(2)
'Datei nicht gefunden --> Rückgabe errorlevel 2  

If mins <= 0 Then WScript.Quit(2)
'Parameterwert für "Minuten" negativ oder 0 --> Rückgabe errorlevel 2  

If DateDiff("n", fso.GetFile(f).DateLastModified, Now()) <= mins Then WScript.Quit(1)  
'Datei nicht älter als "Minuten" --> Rückgabe errorlevel 1  

'Datei ist "alt" --> "Normales" Script-Ende mit errorlevel 0  
set fso = Nothing


Der folgende Beispielbatch überprüft die Datei "Z:\Test.txt" auf ein Alter von 30 Minuten
(Annahme: Die obige Script-Datei ist als ISOLD.vbs in "C:\Scripts" gespeichert):

CScript //nologo "C:\Scripts\ISOLD.vbs" Z:\test.txt 30  
if errorlevel 2 goto Fehler
if errorlevel 1 goto jung
echo alt
goto Ende
:Fehler
echo Fehler!
goto Ende
:jung
echo jung
:Ende

HTH
bastla
Biber
Biber 27.08.2006 um 21:50:48 Uhr
Goto Top
Moin cMichel,

nur eine Variation des Themas bzw. der Strategie....
Ich würde es ähnlich wie bastla machen, aber den VBS-Teil nur für die reine DateDiff-Ermittlung verwenden - und die Programmlogik (und Variabilität, also die Prüfung auf x Minuten) im Batch lassen.

Mein VBS-Schnipsel sähe sinngemäß so aus:
'----GetFileMinutes.vbs  
Set fso = CreateObject ("Scripting.FileSystemObject")   
Set f = fso.getfile(wscript.arguments(0)) 
WScript.echo DateDiff("n", f.DateLastModified, now())   
'------snapp GetFileMinutes.vbs  

Der Aufruf wäre entsprechend
CScript //nologo GetFileMinutesvbs DeineDatei.xyz
...und die Rückgabe eine Zahl (geändert von ... Minuten).

Die Auswertung im Batch entsprechend:
for /f %%i in ('cscript //nologo GetfileMinutes.vbs DeineDatei.xyz') do if %%i GEQ 30 Goto IsOlder  
goto :NothingToDo
....
:IsOlder
....bla....
::-----Ende der Skizze

Vorteil ist (für mich), dass ich die drei VBS-Zeilen schnell aus dem Batch heraus mit ECHO erzeugen kann.
Falls nicht das letzte Änderungsdatum das Kriterium ist, sondern das Entstehungsdatum, dann im VBS-Snippet ändern auf f.DateCreated.

Gruß
Biber
cmichel
cmichel 28.08.2006 um 08:38:20 Uhr
Goto Top
Hi ihr lieben,

Erstmal Vielen Dank für eure Mühe!
Leider müssen wir VB aussen vor lassen, da alles unter DOS abläuft.
Hintergrund ist das durchsuchen von Festplatten nach Dateienamen in eine txt Datei
Da dies sehr Zeitaufwendig ist brauch dies nicht bei jedem start der batch datei zu erfolgen.

Vielleicht eine andere Idee...
Man speichert die aktuelle Zeit zwischen und wenn 30 min vergangen sind soll er die Festplatten durchsuchen oder ansonsten kann der Teil übersprungen werden.
Vielleicht wäre das unter DOS machbar?

Vielen Dank für die Hilfe!

Gruß
Christof
Biber
Biber 28.08.2006 um 09:18:21 Uhr
Goto Top
Moin Christof,

dann teile uns aber mit, von welchem Betriebssystem wir ausgehen müssen.
Ab Win2k sollte sich auch mit native Batch eine Lösung finden lassen - bei Win95/Win98 wird es sicherlich etwas holzig.

Gruß
Biber
cmichel
cmichel 03.09.2006 um 09:48:26 Uhr
Goto Top
Hallo Biber,

Das OS ist WinXP Prof.

Gruß
Christof
Biber
Biber 03.09.2006 um 13:18:10 Uhr
Goto Top
Moin cmichel,

na, ich weiß nicht, ob Du das richtig verstanden hast...
Leider müssen wir VB aussen vor lassen, da alles unter DOS abläuft.
Es geht gar nicht um VB, sondern um VBSkript und überhaupt nicht um DOS, sondern um die CMD.exe

In Bereich "Batch & Shell" steht ein kleines Tutorial zum Thema "Umgang mit Datums- und Zeitvariablen im Batch" mit einer allgemein verwendbaren Datum/Zeit-Aufdrösel-Batchdatei namens GetAllDateTimeInfos.bat.
Diese nutzt aber wiederum vorhandene VBS-Funktionalitäten, alldieweil im Batch keinerlei Datumsberechnungen unterstützt werden.
Und man/frau schlicht und einfach albern wird, wenn es trotzdem über native Batch abgefackelt werden soll.

Das kann ich mit einem Pur-Batch-Schnipsel belegen:
:: --snipp GetFileMinutesDemo.bat Parameter1 Filename/File-Wildcards
:: Placed in the Public Domain for Educational Purposes Biber 2006
@echo off & setlocal
call :DateToDays todayInDays %date%    && REM Heutiges Datum  als Ganzzahl
call :TimeToMins todaysMinutes %time%  && REM Minuten sei Mitternacht als Ganzzahl

For %%i in (%1) do call :CompareMinutes %%i %todayInDays% %TodaysMinutes%
goto :eof
~~~~~~~~~~ Ende des Hauptbatches... es folgen geCALLte Unterroutinen
:CompareMinutes Parameter1:Datei; Para2: Heute als Ganzzahl; Para3: Minuten heute seit Mitternacht 
For /f "tokens=1-2" %%a in ("%~t1") do (  
   call :DateToDays FileInDays %%a  && REM DateiDatum als Ganzzahl
   call :TimeToMins FileMinutes %%b && Rem Datei-Minuten seit Mitternacht
)
if %fileinDays% GEQ 25550 (echo [GTR] %~t1 %~f1 ist definitiv nicht aus diesem Jahrhundert) && goto:eof
REM wenn Jahresendzahl größergleich 70 dann annehmen 1970....1999. [70*365 = 25550]
Set /a "yesterday=%2-1"  
if %fileinDays% LSS %yesterday% (echo [GTR] %~t1 %~f1 ist definitiv älter als 30 Min) && goto:eof
if %fileinDays% LSS %2                  Set /a "TodayCompMinutes=%3+(60*24)-30"       
If %fileinDays% LSS %2 if 1%todayCompMinutes% GTR 1%fileMinutes% (
    (echo [GTR] %~t1 %~f1: von gestern; älter als 30 Minuten)  && goto :eof
) else (
    (echo [LEQ] %~t1 %~f1: von gestern; jünger als 30 Minuten) && goto :eof
)
REM verbleibender Fall: Datei ist von Heute:
Set /a "FileMinutes+=30"  
If %fileminutes% LSS %3 (
   echo [GTR] %~t1 %~f1: von heute; älter als 30 Minuten
) else (
   echo [LSS] %~t1 %~f1: von heute; jünger als 30 Minuten
)  
goto :eof
~~~~~~~~~~~
:DateToDays ; Para1=Variablenname; Para2 [,Para3] :Datum als "[ttt] TT.MM.[JJ]JJ"  
For %%i in (%2 %3) do set "now=%%i"  
for /f "tokens=1-3 delims=./" %%a in ("%now%") do (  
      Set /a "%1=((%%c%%100)*365)+((1%%b-100)*12)+(1%%a-100)" )  
goto :eof
~~~~~~~~~~
:TimeToMins Parameter1: Variablenname Parameter2:Zeit im Format hh:mm
For /f "tokens=1-2 delims=:" %%a in ("%2") do set /a "%1=(1%%a-100)*60+(1%%b-100)"  
:: ---snapp GetFileMinutesDemo.bat

Wenn ich diesen Schnipsel gegen ein oder mehrere Dateien laufen lasse (um 13:07h!), bekomme ich so etwas am CMD-Prompt:
$cmd$d:\temp\GetFileMinutesDemo.bat *.txt
[GTR] 04.04.00 23:19  Z:\putinenv.txt ist definitiv älter als 30 Min
[GTR] 03.09.06 11:37  Z:\vonheute.txt: von heute; älter als 30 Minuten
[GTR] 02.09.06 18:43  Z:\vongestern.txt: von gestern; älter als 30 Minuten
[GTR] 03.09.06 12:36  Z:\vonheute2.txt: von heute; älter als 30 Minuten

Z:\>
$cmd$echo xx>>vonheute2.txt

Z:\>
$cmd$d:\temp\GetFileMinutesDemo.bat *.txt
[GTR] 04.04.00 23:19  Z:\putinenv.txt ist definitiv älter als 30 Min
[GTR] 03.09.06 11:37  Z:\vonheute.txt: von heute; älter als 30 Minuten
[GTR] 02.09.06 18:43  Z:\vongestern.txt: von gestern; älter als 30 Minuten
[LSS] 03.09.06 13:07  Z:\vonheute2.txt: von heute; jünger als 30 Minuten

... das heißt, Für jede angefasste/abgefragte Datei bekommst Du eine Zeile mit dem Dateinamen und dem abprüfbaren String "[GTR]", falls die Datei älter als 30 Minuten ist bzw "LSS", wenn die Datei jünger ist als 30 Minuten.

Du kannst also, wie es hier im Forum schon mehrfach vorgehampelt wurde, mit "Find" und Prüfung des Errorlevels Deine Programmlogik steuern.
Beispiel:
d:\temp\GetFileMinutesDemo.bat vonheute2.txt|find "[LSS}" >nul && echo Datei ist jünger als 30 Minuten  
-oder-
d:\temp\GetFileMinutesDemo.bat vonheute2.txt|find "[LSS}" >nul || echo Datei ist älter als 30 Minuten  

Aber dazu findest Du genug Beispiele hier - ich wollte ja nur den Algorithmus skizzieren.

Gruß
Biber
P.S. Ist -wie geschrieben- albern, dieses Rad neu zu erfinden bzw. native Batch hier als Werkzeug zu verwenden.
Für den Rest meiner monatlichen Admin-Aufgaben brauche ich weniger Zeilen.
cmichel
cmichel 04.09.2006 um 08:08:08 Uhr
Goto Top
Hallo Biber,

Ja das wird mir auf jeden fall weiterhelfen!
Vielen Dank!

Gruß
Christof
Biber
Biber 04.09.2006 um 09:09:36 Uhr
Goto Top
Moin cmichel,

dennoch, auch wenn ich mich damit wiederholen sollte, halte ich bastla's Ansatz mit Nutzung der DateDiff()-Funktion von VB/JScript für die "richtige" Lösung und habe es entsprechend bewertet.

Ich empfehle Dir dringend noch einmal die Klärung, ob wirklich auf dieses Standardwerkzeug verzichtet werden muss.
Sicherheitsrisiken werden aus meiner Sicht durch die Vorteile kompensiert.
Und, falls Sicherheitsaspekte der Grund gegen VBS gewesen sein sollten:
Eure Rechner könnte ich auch mit native Batch zu mehr oder weniger dekorativen Briefbeschwerern umfunktionieren.
Und wenn ich das könnte, gibt es sicherlich weitere 2 Millionen DAUs mit ausreichender krimineller Energie und Kreativiät.

Bitte setze den Beitrag auf "Gelöst", wenn für Dich keine wesentlichen Fragen mehr offen sind.

Danke
Biber
cmichel
cmichel 04.09.2006 um 12:53:41 Uhr
Goto Top
Hi Biber,

Das script habe ich unter date.bat gespeichert.
Ich habe gerade mal versuch die batch mal aufzurufen mit:
date files.txt
Dann kommt bei mir der Hinweis:
Eingegebenes Datum kann nicht übernommen werden.
Geben Sie das neue Datum ein: (TT-MM-JJ)

Was mache ich da falsch?
Gruß
Christof
Biber
Biber 04.09.2006 um 13:12:36 Uhr
Goto Top
Moin cmichel,

das kollidiert mit dem gleichlautenden internen CMD-Befehl "date", der Vorrang hat.

Abhilfe:
a) recommended: Deine *.bat-Datei umbenennen z.B. in Find30MinFiles.bat oder AlleDateienÄlterAlsEineHalbeStundeSuchen.bat oder Karlheinz.bat...
...jedenfalls nicht date.bat

b) nicht empfohlen:
Datei so lassen, wie sie heißt und explizit mit Pfadangabe aufrufen, z.B c:\bätsche\date.bat

Gruß
Biber
cmichel
cmichel 04.09.2006 um 13:41:56 Uhr
Goto Top
Hi Biber,

Jo funktioniert!
Vielen Dank für deine Hilfe!!!

Gruß
Christof