diekoenigs
Goto Top

Kopieren von Dateien ab gestern Abend 20 Uhr - Jede Woche

Hallo liebe Helfer.

Habe alles soweit mit eurer hilfe hinbekommen und schon kommt die nächste Aufgabe. face-smile

Ich muss jeden Samstag einen Job laufen lassen, der alle Dateien, die am Vortag ab 20 Uhr erstellt wurden, kopieren.
Robocopy mag nur /MAXAGE und so.. aber keine Uhrzeit. face-sad

Wie bekomme ich das hin?

gruß
Alex

Content-Key: 206976

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

Printed on: April 20, 2024 at 03:04 o'clock

Member: MrNetman
MrNetman May 24, 2013 at 13:39:28 (UTC)
Goto Top
die Variablen %date% %time% und xcopy/robocopy in einer Batchdatei ...

Gruß
Netman
Member: diekoenigs
diekoenigs May 24, 2013 at 13:58:50 (UTC)
Goto Top
Danke MrNetman,

jedoch weiss ich nicht wie ich das benutzen kann..

Habe sowas gefunden..
Kann es aber nicht interpretieren bzw. verstehe die Anweisung nicht.

copy meinedatei.xyz "%date% %time:~0,2%-%time:~3,2%-%time:~6,2%"

Ich denke das würde mir schon helfen.

Gruß
Alex
Member: diekoenigs
diekoenigs May 24, 2013 at 14:30:11 (UTC)
Goto Top
Ich kann mit:

Get-ChildItem -Recurse E:\ | Where-Object {$_.LastWriteTime -gt (Get-Date).AddHours(-20)}

eine Liste mit den Dateien anzeigen lassen. (powershell)
Aber wie kann ich dieses Ergebnis an den Copy-Befehl (xcopy oder Robocopy) übergeben?

Gruß
Alex
Member: rubberman
rubberman May 24, 2013 at 22:39:52 (UTC)
Goto Top
Hallo diekoenigs,

ggf. könnte dir WMIC helfen.
Teste folgenden Batch:
@echo off &setlocal

set "fDrive=%~d0" &rem Laufwerksbuchstabe und Doppelpunkt (zB. C:)  
set "fPath=%~p0"  &rem Pfad mit vor- und nachgestelltem Backslash (zB. \test\abc\)  

for /f %%i in ('WMIC PATH Win32_LocalTime GET Year^,Month^,Day /Value^|findstr .') do set /a %%i  
:: echo heute %Year% %Month% %Day%

set /a a=14-Month,a/=12,b=Year+4800-a,c=Month+12*a-3,d=153*c+2
set /a d=d/5+Day+b*365+b/4-b/100+b/400-2
set /a e=4*d+3,e/=146097,f=-e*146097,f/=4,f+=d
set /a g=4*f+3,g/=1461,h=-1461*g,h/=4,h+=f,i=5*h+2,i/=153,Day=153*i+2,Day/=5
set /a Day=-Day+h+1,Month=-i/10,Month*=12,Month+=i+3,Year=e*100+g-4800+i/10
:: echo gestern %Year% %Month% %Day%

if %Month% lss 10 set Month=0%Month%
if %Day% lss 10 set Day=0%Day%
set "LastModified=%Year%%Month%%Day%200000.000000+000"  
:: echo suche Timestamp groesser %LastModified%

for /f "delims=" %%i in (  
  'WMIC DATAFILE WHERE "drive='%fDrive%' AND path='%fPath:\=\\%' AND LastModified > '%LastModified%'" GET Name /Value'  
) do for /f "delims=" %%j in ("%%i") do (  
  set "%%j"  
  call :copy
)
pause
goto :eof

:copy
echo kopiere "%Name%"  
goto :eof
Falls die gesuchten Dateien gefunden werden, ersetze Zeile 31 mit einer entsprechenden Kommandozeile zum Kopieren.

Grüße
rubberman
Mitglied: 76109
76109 May 25, 2013 at 13:07:08 (UTC)
Goto Top
Hallo rubberman!

Deine Berechnungen sind mir irgendwie zu Hoch, aber vom Ergebnis her (in Codezeile 18), sollten es auch die beiden Script-Beispiele tunface-sad

Wenn's ein bestimmter Tag der Woche sein soll, wäre die Vorgabezeit vielleicht so etwas einfacher zu ermitteln:
@echo off & setlocal
Set So=1 & Set Mo=2 & Set Di=3 & Set Mi=4 & Set Do=5 & Set Fr=6 & Set Sa=7

set "StartDay=%Fr%"  
set "StartTime=200000.000000+000"  

set "S=%temp%\GetStartTime.vbs"  
>%S% Echo D=Date-Weekday(Date,WScript.Arguments(0))+1:WScript.Echo Year(D)^&Right("0"^&Month(D),2)^&Right("0"^&Day(D),2)  

for /f "tokens=1" %%d in ('cscript //nologo "%S%" %StartDay%') do Set "LastModified=%%d%StartTime%"  

echo %LastModified%
Wobei in diesem Beispiel, von Samstag bis Donnerstag das LastModified vom letzten Freitag zurückgegeben wird...

Oder wenn's eine bestimmte Anzahl von Tagen sein soll, dann sollte es auch so gehen:
@echo off & setlocal

set "AnzahlTage=1"  
set "StartZeit=200000.000000+000"  

set "S=%temp%\GetStartTime.vbs"  
>%S% Echo D=Date-WScript.Arguments(0):WScript.Echo Year(D)^&Right("0"^&Month(D),2)^&Right("0"^&Day(D),2)  

for /f "tokens=1" %%d in ('cscript //nologo "%S%" %AnzahlTage%') do Set "LastModified=%%d%StartZeit%  

echo %LastModified%

Gruß Dieter
Member: rubberman
rubberman May 25, 2013 updated at 14:08:12 (UTC)
Goto Top
Hallo Dieter!

Deine Berechnungen sind mir irgendwie zu Hoch
Eigentlich ist es nur ein Algorithmus für Datum zu Julianischem Datum (fortlaufende Nummerierung der Tage) und wieder zurück. Findet sich so oder ähnlich im Internet. Das "-2" am Ende der Zeile 10 ist dafür verantwortlich, dass das gestrige Datum berechnet wird.
Batch kennt leider keinen Datentyp für Datum und Zeit, erst recht keine Arithmetik dafür. Darum ist so etwas nötig wenn man bei Batch pur bleiben möchte.

aber vom Ergebnis her (in Codezeile 18), sollten es auch die beiden Script-Beispiele tun
Natürlich kann man auch VBScripts dafür einbinden face-wink Ist jedem selbst überlassen.

Grüße
rubberman
Mitglied: 76109
76109 May 25, 2013 at 15:43:26 (UTC)
Goto Top
Hallo rubberman!

Achsooo, Julianisches Datumface-smile

Danke für die Info! Werde mich bei Gelegenheit mal damit auseinandersetzenface-wink

Gruß Dieter
Member: rubberman
rubberman May 25, 2013 updated at 16:25:57 (UTC)
Goto Top
Hallo Dieter!

Als Vorlage haben mir diese beiden Funktionen gedient:
DateToMJD und MJDToDate
Um eine Punktlandung auf einem Stichtag (für das "echte" Julianische Datum der 1. Januar 4713 B.C.) zu erreichen, ist noch ein entsprechendes Offset nötig. Da ich beide Berechnungen nacheinander durchführe, kürzt sich dieses Offset natürlich raus.

BTW Wie du weißt wird ein DateTime Wert in VBScript intern auch als numerischer Wert gehandelt. Du kannst getrost davon ausgehen, dass für die Darstellung als Datums- oder Zeitstring ganz ähnliche Algorithmen ablaufen.

Grüße
rubberman
Member: Biber
Biber May 25, 2013, updated at May 26, 2013 at 08:58:16 (UTC)
Goto Top
Moin didi und rubberman,

ehrlich gesagt wären mir eure Lösungen etwas suspekt, wenn ich diekoenigs hiesse bzw. eigentlich als Anfänger nur fremde Codezeilen verwenden will, bei denen ich nachvollziehen kann, was da abgeht.

Ich würde daher folgenden uneleganten, aber vielleicht auch für Laien verständlichen Weg skizzieren:

Anforderung. Kopiert werden sollen aus einem Verzeichnis alle geänderten Dateien seit gestern 20h.

Ich kann in zwei Teilprobleme zerlegen.
Das sind doch anders ausgedrückt alle Dateien dieses Verzeichnisses
  • mit dem Tagesdatum von heute==25.05.2013==%date%
  • und die mit dem Tagesdatum von Gestern=24.05.2013 und einer Uhrzeit größer 20.00h

Wie oben geschrieben wurde - mit Datumtyp-Werten rechnen geht nicht im Batch, weil Batch keinen Datentyp "Datum" kennt.

Aber ich kann dafür einen (auch wieder wie oben bei didi per Batch im %temp%-Verzeichnis erzeugten) VBS-Einzeiler aufrufen, der mir "gestern" zurückgibt.

'Gestern.vbs  
Wscript.Echo DateAdd("d", date, -1)  

Damit kann ich wiederum im Batch eine Variable %gestern% füllen:
..
set "S=%temp%\Gestern.vbs"  
..
for /f %%d in ('cscript //nologo "%S%"') do Set "gestern=%%d"   
...

Wenn ich dann im Batch das "heute" (ja, ist in %date%) und das "Gestern" (ist in %gestern%) kenne, dann ist der Rest einfach:

[Edit] Nur zur Erläuterung für Nicht-täglicher-Bätcher
Denn wenn ich einzelne Dateien als Variable %i durch eine FOR-Anweisung nudele, dann steht mir Datum/Zeit als Text im Format [tt.mm.jjjj hh:nn.ss] in der Variablen %~ti zur Verfügung. Die beiden möglichen Datumswerte "gestern" und "heute" kann ich mit einem exakten Textvergleich prüfen, eine Uhrzeit größer 20:00 mit einem GEQ (größer gleich).
[/Edit]


Beispiel am CMD für die zwei Kopierläufe für Heute+Gestern, wenn %gestern% mit z.B. 24.05.2013 gefüllt ist

#Vergleich auf "Heute"-Dateien
>For %i in (D:\quelle\*.*) do @for /f "tokens=1,2" %a in ("%~ti") do @if [%a]==[%date%] @echo kopiere "%i" x:\nachZiel\

#Vergleich auf Dateien von "gestern" UND >= 20:00h
>For %i in (D:\quelle\*.*) do @for /f "tokens=1,2" %a in ("%~ti") do @if [%a]==[%gestern%] @if [%b] GEQ [20:00] @echo kopiere "%i" x:\nachZiel\

Ich denke mal, wenn das Vorgehen klar ist, dann lassen sich diese Baukastenzeilen auch einen Batch packen, der dann -und das wäre eben mein Hauptanliegen- von einem Nicht-Coder anpassbar und wartbar ist.

Ich kann doch keinem Forumsneuling erzählen, dass er über 1. Januar 4713 B.C. und Julianische Kalender recherchieren gehen muss, um auf das Datum von "Gestern" zu kommen. Der meldet sich sofort wieder ab. face-wink

Grüße
Biber
Member: rubberman
rubberman May 25, 2013 updated at 18:43:38 (UTC)
Goto Top
Hallo Biber,

OK, OK. Zur Ehrenrettung: Der "Forumsneuling" ist seit 2008 dabei und nennt sich Administrator. Ich denke wer Deine dreifach verschachtelten FOR Schleifen am Prompt versteht, ist auch in der Lage unsere Lösungen nachzuvollziehen und umgekehrt face-wink Uuund "Julianischer Kalender" NEQ "Julianisches Datum" (aber das ist Korinthenkackerei) face-smile

Ich gebe zu, dass ich die Algorithmen für das Julianische Datum auch nicht herleiten kann, das ist aber auch Nebensache. Was sie tun, sollte klar sein.
WMIC halte ich für ein Tool, das viel zu wenig Beachtung findet, obwohl es eine Menge Potenzial hat. Ich wollte einfach mal einige Möglichkeiten aufzeigen.

Grüße
rubberman
Member: Biber
Biber May 26, 2013 updated at 14:58:07 (UTC)
Goto Top
Moin rubberman,

ich gehe davon aus, dass du ebenso wie didi weisst, wie eure Kommentare und Codebeispiele hier geschätzt werden und diese fast immer blind als Copy&Paste-Lösung übernommen werden können.

Ich habe mich eigentlich nach längerem stillen Mitlesen hier eingeschaltet wegen drei Details, die auch in meiner täglichen Arbeit ständig Risiko bedeuten:

  • trotz vermeintlich detailliert formulierter Anforderung wird locker variiert. Aus "seit gestern nach 20h" wird bei didi "alles seit Freitag 20h, falls heute Sa bis Donnerstag ist". In der Powershell-Variante wird sogar "alles jünger als 20 Stunden" daraus. Und am Schlimmsten: wenn mal aus irgendwelchen Gründen der Jeden-Samstag-automatisch-Job nicht läuft, dann habe ich weder eine Fehlerinfo darüber noch einen Plan B, wie ich die Kopiererei nachhole. didis Variante versucht ja, dieses Manko auszubügeln, ohne den Beitragsersteller auf diese Sollbruchstelle hinzuweisen.

  • ich empfinde es immer als grosses Risiko, wenn der Code nicht ohne weiteres nachvollziehbar ist und letzten Endes nur vom Programmierer selbst angepasst werden kann

  • und das dritte Unbehagen kam von der - ich sach ma' Unverhältnismäßigkeit der Mittel. Wenn ich zum Ermitteln der Dateien drei Werkzeuge brauche (Batch, VBS und WMIC), dann ist ja wohl keines der drei Tools allein so richtig geeignet dafür.

Ein durchgängiger Ansatz z.B. ganz in VBS wäre mir da lieber (über das FileSystemObject und Property .DateLastModified ist das auch kein Hexenwerk) oder auch der Einsatz eines One-Trick-Tools wie WasFile.exe von Horst Schaeffer.

Wie dem auch sei - mögliche Lösungswege sind nun reichlich da, ich warte jetzt auch auf den Beitragsersteller.

Grüße
Biber
Mitglied: 76109
76109 May 26, 2013 at 13:20:02 (UTC)
Goto Top
Hallo Biber!

Ein durchgängiger Ansatz z.B. ganz in VBS wäre mir da lieber (über das FileSystemObject und Property .DateLastModified ist das auch kein Hexenwerk) oder auch der Einsatz eines One-Trick-Tools wie WasFile.exe von Horst Schaffer.
Den Gedanken hatte ich schon im Hinterkopf, aber da das Ganze theoretisch auch rekursive über mehrere Ordner ablaufen könnte, wieder verworfen, weil mir persönlich Batch in diesem Fall als besser geeignet erscheint und rubbermans Script, wenn auch ein wenig abgehoben, finde ich durchaus interessant...face-wink

Wie dem auch sei - mögliche Lösungswege sind nun reichlich da, ich warte jetzt auch auf dem Beitragsersteller.
Das wäre auch mein Vorschlag gewesenface-wink

Noch einen schönen Sonntag!

Gruß Dieter