BATCH- Dateien mit heutigem datum in anderen ordner kopieren?
Hallo.
Wie bekomme ich es mittels batch -Datei hin, dass Logfiles, die am heutigen Datum erstellt wurden (und nur diese) in einen anderen Ordner kopiert werden?
Die Logfiles haben unterschiedliche Namen und die Endung .log
jetzt bräuchte ich nur die möglichkeit zu per batch cmd abfrage zu erkennen, welche Datei am heutigen Tag erstellt wurde und diese müsste dann woanders hinkopiert werden.
Copy befehle etc. ist alle kein problem. Nur die Abrage nach dem erstelldatum , daran hapert es bei mir. schön wäre es auch, wenn es Systemunabhängig geht (also egal ob englische oder deutsche Schreibweise vom Datum)
4 Antworten
was ssoul33 da gepostet hat kann nicht funktionieren,
Ob mancheiner überhaupt weiß was fremder Code macht?....
... spätestens wenn Leerzeichen in Dateinamen sind , kommt die gesamte Reihung der Tokens durcheinander.
Also immer mit Dir /b "pfad datei joker " arbeiten und und alles nötige über die Parameter-Extension abrufen .
dir /b /s "c:\*.log" sucht alle unterverzeichnisse ab...
ersetze a:\backup durch deinen Zielpfad
ein Unterordner mit dem aktuellen Datum wird automatisch erzeugt...
@echo off
setlocal enabledelayedexpansion
set "basefolder=C:/" & rem Basisordner von dem aus rekursiv gesucht wird
set "nowDate=%date%" & rem verhindert Mitternachtsabbruch
set "destFolder=a:/backup" & rem dein Zielordner
rem diesZeile kannst Du entfernen wenn dir das mit dem Datum im Ordnernamen nicht gefällt:
set "destfolder=%destFolder%\%nowDate:.=_%" & rem ZielOrdner =a:\backup\tag_monat_jahr .... könntest so jeden Tag einen Backup machen ohne die gestrigen dateien zu überschreiben
md "%destFolder%" 2>nul & rem Wenn dieser nicht existiert erstelle ihn :p wenn er existiert schicke die Fehlermeldung in den Orcus
echo durchsuche %baseFolder% und alle unterverzeichnisse nach *.log:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%basefolder%*.log"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, !fileDate! , %nowDate%
copy /b "%%a" "%destFolder%" >nul 2>&1 && echo %%~nxa nach %destFolder% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!
echo:
)
)
pause
exit /b
Es werden alle Dateien gesichert die am heutigen Tage verändert oder erzeugt wurden.
Wenn Dir dies nicht zusagt gib bescheid.
Dateien die wirklich nur neu erzeugt wurden und die es zuvor noch nie gab auszusieben ist ein riesiger Aufwand... und mach auch wenig Sinn.
damit Du auch morgen das gleiche abziehen kannst. Ändert sich der Name des Zielordners automatisch.
Bei Dateien , die nicht Kopiert werden konnten erscheint die Meldung: Zugriff verweigert!!.
Ursache wären meist keine Adminrechte oder das die Dateien durch einen anderen Prozess geöffnet sind...
Da das ganze Laufwerk durchsucht wird kann es anfangs wirken als wäre die Batch nicht in Ordnung... ein blick auf die Festplatten-LED dürfte anderes aussagen. ( bei einer vollen 500er HDD kann das schon mal 30...40 sekunden brauchen...) ich hääte zwar eine Spielerei einbauen können, welche Dir Aktivität vorgaukelt.... dumme Spielerei
Ich hätte noch eine Frage. Die Batch kopiert ja nun zuverlässig alle Dateien in einen Bestimmten Unterordner und zippt diesen. Das geschieht immer um 23:59 Uhr jeden Abend. Nun kommt es aber vor, dass das Zippen über 00:00 Uhr hinausgeht und dann wird der gezippte Ordner vom Vortag in den ordner vom aktuellen Tag auch mit aufgenommen. Wie kann ich denn .zip von der Suche ausschließen, damit das nicht mehr passiert?
da ich 23:59 der Variable %nowDate% das aktuelle Datum zuweise und lege ich erstmal fest das nur Dateien betroffen sind, welche zum Zeipunkt des Starts der Batch dam Zeitstempel entsprechen. Zudem sind in meinem Beispiel nur Dateien mit der Endung .log vom Kopiervorgang betroffen und nicht Zip-Dateien.... ergo werden Diese auch nicht kopiert.
for /f "tokens=*" %%a in ('dir /b /s /a-d "%basefolder%*.log "') do (
set "fname=%%~a"
...usw...
wenn Du an diesem Mechanismus etwas verändert hast, könntest Du zip-Dateien zB durch ein Konstrukt wie :
...
if [%%~xa] neq [.zip] (copy /b "%%a" "%destFolder%" >nul 2>&1 && echo %%~nxa nach %destFolder% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!)
...
vom Kopiervorgang ausschließen...
aber wie normalerweise dürften ohnehin keine .zip involviert sein...
Wenn Du was umgebaut hast poste einfach den Code und ich schau mal was wo falsch läuft . vielleicht lässt sich auch an der ziproutine schrauben.
Ich vermute mal das Du wie die meisten Batcher mit einem generierten VBScript arbeitest...
So sieht mein Script aktuell aus:
@echo on
setlocal enabledelayedexpansion
set "_zipper=D:\railsys\enterprise\bin\tools\7z.exe"
set "_log_path_rs=D:\railsys\enterprise\log\" & rem Basisordner von dem aus rekursiv gesucht wird
set "_log_path_tomcat=D:\railsys\3rdparty\apache-tomcat-8\logs\" & rem Basisordner von dem aus rekursiv gesucht wird
set "nowDate=%date:~4,10%" & rem verhindert Mitternachtsabbruch
rem IP-Adresse ermitteln
for /f "delims=[]" %%a in ('ipconfig ^| find /i "ipv4" ^| find /i "10."') do set ip= %%a
set _ip=%ip:~40,15%
rem Systemunabhängiges Datum erzeugen
for /f "tokens=2,3,4 delims=," %%g in ('wmic path win32_localtime get day^,month^,year ^/format:csv^|findstr /i %COMPUTERNAME%') do (
set day=%%g
set month=%%h
set year=%%i
)
set _datum= %day%.%month%.%year%
::Archivnamen zusammensetzen
::--------------------------------------------------------------
set ARCHIVNAME=Logs_%_ip%_vom_%_datum%
set "destFolder1=%_log_path_rs%%ARCHIVNAME%\RailSys_Logs\"
md "%destFolder1%" 2>nul
echo durchsuche %baseFolder% und alle unterverzeichnisse nach *.log:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.*"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, !fileDate! , %nowDate%
copy /b "%%a" "%destFolder1%" >nul 2>&1 && echo %%~nxa nach %destFolder1% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!
echo:
)
)
set "destFolder2=%_log_path_rs%%ARCHIVNAME%\Tomcat_Logs\"
md "%destFolder2%" 2>nul
echo durchsuche %_log_path_tomcat% und alle unterverzeichnisse nach *.log:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_tomcat%*.*"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, !fileDate! , %nowDate%
copy /b "%%a" "%destFolder2%" >nul 2>&1 && echo %%~nxa nach %destFolder2% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!
echo:
)
)
::Zip Archiv erzeugen
::--------------------------------------------------------------------
start /wait %_zipper% u "%_log_path_rs%%ARCHIVNAME%".zip "%_log_path_rs%%ARCHIVNAME%"
::Verzeichnis löschen
::--------------------------------------------------------------------
rd /s /q "%_log_path_rs%Logs_%_ip%_vom_%_datum%"
endlocal
Ich bin kein Profi. Das Script an sich funktioniert auch, nur das es scheinbar nicht nur .log-dateien mit einbezieht, sondern auch .zip. Außerdem soll es nur im angegebenn Ordner suchen und nicht in etwaigen Unterordnern
sooo... jetz hatte ich mal Deine Ordnerstruktur auf meiner Maschine nachgebaut...
Dafür das Du alle irgendwie zusammengepastet hast waren erstaunlich wenig Fehler drin und das was falsch lief habe korrigiert un mit einem Kommentar versehen.
Was unnötig war habe ich rausgeschmissen...
habe ein paar fröhliche dummy.logs Verteilt, die wurden alle wunderbar archiviert... und da nun die .zip-dateien ihren eigenen Ordner "D:\railsys\log-Archives" sind sie aus dem Schussfeld...
im Prinzip hätte statt:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.*"') ...usw
ein:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.log"') ... usw.
genüg um die Sache zu regeln . Da die kopierRoutine meine "Handschrift " trägt muss das wohl auch mal so gewesen sein XD..
Jetzt kann's auch bei *.* bleiben egal... die zips sind nicht mehr im Wege...
das ... find /i "10." beider Ip entzieht sich auch irgendwie meinem Verständnis. Liefert bei Dir iponfig mehr als eine ipv4 ?
egal ich hab's zurecht gefriemelt. Das es hübsch ist... ;)
@echo off
setlocal enabledelayedexpansion
set "_zipper="D:\railsys\enterprise\bin\tools\7z.exe""
set "_log_path_rs=D:\railsys\enterprise\log\" & rem Basisordner von dem aus rekursiv gesucht wird
set "_log_path_tomcat=D:\railsys\3rdparty\apache-tomcat-8\logs\" & rem Basisordner von dem aus rekursiv gesucht wird
rem zipArchive bekommen einen eigenen Ordner, das löst alle probleme auf einen Schlag
rem und Du hast ordnung auf der Festplatte
set "_archiv_path=D:\railsys\log-Archives"
set "nowDate=%date:~0,10%" & rem verhindert Mitternachtsabbruch
rem IP-Adresse ermitteln korrigiert by Erzesel : Du kannst nur eine Ip haben, also brauchst Du eigentlich nicht zusätzlich nach 10... filtern oder tunnelst Du einen Hamachiserver oder sowas?
rem wir wollen nur die Angaben nach dem Doppelpunkt ;) also das 2.Token das ist die IP
for /f "tokens=2 delims=:" %%a in ('ipconfig ^| find /i "ipv4" ^| find /i "10."') do (set "_ip=%%a")
rem Normalerweise reicht das:
rem for /f "tokens=2 delims=:" %%a in ('ipconfig ^| find /i "ipv4"') do (set "_ip=%%a")
rem Leerzeichen aus %_ip% entfernen ...if verhindert Fehlinterpretation bei leerer Variable:
if "%_ip%" neq "" set "_ip=%_ip: =%"
::Archivnamen zusammensetzen
::--------------------------------------------------------------
set ARCHIVNAME=Logs_%_ip%_vom_%nowDate%
rem keine ahnung warum Du die Archive im Log-Ordner platzierst
rem das gibt nur unnötiges Gerangel ein schöner eigenständiger Ordner für Archive ist besser.
rem für copy darf der Zielpfad nicht mit einem backslash enden!
set "destFolder1=%_archiv_path%\%ARCHIVNAME%\RailSys_Logs"
md "%destFolder1%" 2>nul
echo durchsuche %_log_path_rs% und alle unterverzeichnisse nach *.log:
rem keine Ahnung warum du nach *.* suchst wenn Du *.log möchtest?
rem for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.log"') ... wäre dann richtig...
rem ist jedoch unwichtig geworden da die Archive ihren eigenen Ordner bekommen haben
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.*"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, Tag der letzen Aenderung=!fileDate! , Heutiger Tag=%nowDate%
copy /b "%%a" "%destFolder1%" >nul 2>&1 && echo %%~nxa nach %destFolder1% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!
echo:
)
)
set "destFolder2=%_archiv_path%\%ARCHIVNAME%\Tomcat_Logs"
md "%destFolder2%" 2>nul
echo durchsuche %_log_path_tomcat% und alle unterverzeichnisse nach *.log:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_tomcat%*.*"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, Tag der letzen Aenderung=!fileDate! , Heutiger Tag=%nowDate%
copy /b "%%a" "%destFolder2%" >nul 2>&1 && echo %%~nxa nach %destFolder2% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^!
echo:
)
)
::Zip Archiv erzeugen ?was sollte das Start /wait? Batch kommt durchaus auch mit Befehlen in Variablen zurecht ;)
::--------------------------------------------------------------------
%_zipper% u "%_archiv_path%\%ARCHIVNAME%".zip "%_archiv_path%\%ARCHIVNAME%"
::Verzeichnis löschen
::--------------------------------------------------------------------
rd /s /q "%_archiv_path%\%ARCHIVNAME%%"
pause
exit /b
set "nowDate=%date:~0,10%": Hier muss ich ~4,10% verwenden, da sonst als Datum Fri \06\01 rauskommt und das passt dann nicht mit dem Abgleich. Genauso kann ich es nicht für die Variable im Ordnernamen verwenden, da durch die Trennung "\" im Datum im Dainamen Unterordner mit erstellt werden Bsp: Logs_IP_vom_Fri_06\ --> 01\..... anstatt Logs_IP_vom_1.6.2018\....
Da das Script auf englischen und deutschen Servern laufen soll, wo sich das Datumsformat unterscheidet, hatte ich die wmic Abfrage eingebaut, da diese immer die Gleiche Tabelle liefert und man sich daraus das Datum selbst zusammensetzten kann.
Du kannst nur eine Ip haben: Die Server sind gehostet und unter ipconfig wurden mir immer 2 Ipv4 Adressen angezeigt, deshalb hab ich speziell nach der IP gesucht, die ,it 10. anfängt. Deine Abfrage funktioniert dennoch mit der richtigen IP
zipArchive bekommen einen eigenen Ordner: Ich hätte sie gern im selben Ordner, da es sonst bei den Kollegen zu Verwirrung führen könnte, wenn sie die gezippten Logs erst woanders, als gewohnt suchen müssten. deshalb hätte ich ja gern, dass .zip-Dateien von dieser Suche ausgeschlossen werden
keine Ahnung warum du nach *.* suchst wenn Du *.log möchtest?: Es gibt auch dienste, die Ihre Logs im .csv Format schreiben, deshalb
was sollte das Start /wait?: Zu Anfang fehlte immer das größte Script. Ich dachte zuerst, dass es zu lange braucht, um in den Ordner kopiert zu werden, der ja gelöscht wird, wenn das Zippen fertig ist. deshalb hab ich das davor gebaut, damit der Löschbefehl nach dem Zippen erst ausgeführt wird, wenn es auch fertig ist. Dass das Log fehlte , hatte dann aber doch andere Gründe und es funktioniert auch ohne Star/wait
Das erklärt so einiges.... :)
Das ~4,10 hat mich am meisten irritiert... auf "normalen" Maschinen kommt dann 6.2018 raus :p
ein wenig seltsam ist Die Rückgabe von %Date% auf eurem Server schon.Wo kommen der Wochentag "Fr" und die Backslashes "\" her?
Normalerweise sieht das Englische bzw US format von %Date% so aus:
%date% %time%
United Kingdom 23/01/1997 09:45:30
United States 1/23/1997 9:45:30 AM
um ein total Dateinamenneutrales Datum zu erzeugen , die BackSlashes oder Punkte ganz einfach in etwas neutrales wie Underline umwandeln...
rem für alle Eventualitäten: ./\ = _
set "nowdate=%date:.=_%"
set "nowdate=%nowdate:/=_%"
set "_datum=%nowdate:\=_%"
echcho _datum
kannst natürlich auch Dein WMI- Konstrukt verwenden... egal...
Wenn ~4,10 auf all euren Maschinen funktioniert und und damit das gleiche Format hat wie %%~ta bei ~0,10 soll's Ok sein...
den Zielordner kannst du selber wieder zurückwurschteln das solltest du hinbekommen
bleibt mir nur die .zip vom kopieren auszuschließen:
if [%%~xa] neq [.zip] ( copy /b "%%a" "%destFolder1%" ....)
%%~xa enthält die .dateiendung ...wenn diese notequal .zip ist wird die die Datei kopiert
so sähe dann der entscheidende Bereich der Batch aus...
...
set "destFolder1=%_log_path_rs%%ARCHIVNAME%\RailSys_Logs"
md "%destFolder1%" 2>nul
echo durchsuche %_log_path_rs% und alle unterverzeichnisse nach Logs:
for /f "tokens=*" %%a in ('dir /b /s /a-d "%_log_path_rs%*.*"') do (
set "fileTime=%%~ta"
set "fileDate=!fileTime:~0,10!" & rem Dateidatum von Dateizeit abtrennen
if [!fileDate!]==[%nowDate%] (
echo %%~a, Tag der letzen Aenderung=!fileDate! , Heutiger Tag=%nowDate%
if [%%~xa] neq [.zip]( copy /b "%%a" "%destFolder1%" >nul 2>&1 && echo %%~nxa nach %destFolder1% kopiert... || echo %%~nxa Zugriff verweigert ^^!^^! )
echo:
)
)
...
robocopy /MAXAGE:n bezieht sich leider nur auf das Änderungsdatum, nicht aber auf das Erstelldatum.
Zum Glück bekommt man aber mithilfe von %~t1 das Erstelldatum einer Datei.
Da ich nicht wusste, welche Ordner du untersuchen möchtest und wo die .log Dateien hinkopiert werden sollen, hab ich das mal als Eingabefeld gelassen:
@set /P "startDir=Zu untersuchen: <Laufwerk:[Pfad]> "
@set /P "destiDir=Zielordner: <Laufwerk:\Pfad> "
if not exist "%destiDir%" md "%destiDir%"
@for /R "%startDir%" %%F in (*.log) do @for /F %%D in ("%%~tF") do @if "%date%"=="%%~D" copy /b "%%~fF" "%destiDir%\"
hier eine kurze Erklärung dazu:
if not exist "%destiDir%" md "%destiDir%"
> erstellt den Zielordner, falls dieser nicht vorhanden ist.
for /R "%startDir%" %%F in (*.log) do ...
> geht alle .log Dateien ab %startDir% durch und macht für jede dieser Dateien ...
... for /F %%D in ("%%~tF") do ...
> Speichert das Erstelldatum der Datei in %%D
... if "%date%"=="%%~D" ...
> Wenn das aktuelle Datum gleich dem Erstelldatum ist, dann mache ...
... copy /b "%%~fF" "%destiDir%\"
> kopieren
~Tim
@echo off
for /f "skip=1 tokens=1-3*" %%a in ('dir/a-d/tc/o-d^|find ":"') do (
if %%a==%date:~-10% (
echo %%a %%d
copy "%%d" "c:\backup\
) else goto:eof
)
Einfach mal googlen--> https://www.computerhope.com/forum/index.php?topic=83883.0
bei "if %%a" wird bei mir immer die Volumesereiennummer abgefragt und nicht das Datum
robocopy /?
Dachte ich auch zuerst dran. Aber MAXAGE ist nicht das Erstelldatum, sondern das Datum der letzten Änderung.
Robocopy /? ... habe ich eingegeben hat nix kopiert. ;)
irgend wie ist Deine Antwort schon fast einer Frechheit...
Auf die Hilfe eines Befehls zu verweisen ist nicht gerade die feine Art , zumal Robocopy eine erschlagende Varietät an Schaltern und Optionen hat...
Nur nicht für diesen Speziellen Fall .
Schreibe doch die Robocopy Befehlszeile, welche genau das tut was für den Fragesteller erwünscht ist.... Dann veneige ich mich vor Dir... oder irgendsowas.. Hut ziehen etc...
Wenn es ginge, hätte ich es mit Robocopy gemacht, statt mich mit For-loops und WMI-Abfragen herumzuschlagen ...
Dies ist ein Ratgeberforum. Und keine Plattform, wo Arbeitsaufträge vergeben werden, die dann kostenlos von anderen erledigt werden.
Der Frage möge sich die Parameter von robocopy in aller Ruhe ansehen und dann seine tägliche Computerarbeit gefälligst selber erledigen.
Wenn er weiter Hilfe braucht, fragt er nach.
Selbst ich als jemand der recht gut auf auf dem Gebiet von Batch zu sein scheint, wäre wirklich interessiert wie Du die Sache mit Robocopy gelöst hättest.
Ich benötige das nicht für meine Arbeit oder sonst irgendetwas , aber es wurmt mich, wenn jemand große Sprüche klopft .
Ich als Batch-Künstler habe mir Robocopy eingehend zur Brust genommen und das schon seit Jahren...
Es hat sicherlich irgendwo seine Berechtigung , aber es ist kein Allheilmittel.
Was die "Arbeitsaufträge" angeht , möglicherweise ist Dir entgangen, das es sich bei den Fragestellungen teilweise um sehr spezialisierte Herausforderungen handelt.
Schau Dich mal um wieviele Leute fragen: "was könnte ich mal Programmieren". Diese Frage stellt sich mir garnicht... Neben GF bin ich auch unter anderem Namen bei Stackoverflow... da gehen die Aufgaben nie aus...
Andere Leute lösen Kreuzworträtsel. Unsereiner jongliert lieber mit %%%%%%%s for's und if's .
Manchmal steht man sogar mit sich selbst im Wettbewerb um eine noch elegantere Lösung zu finden... und dann gibt es eben eine Nachtrag.
...Du schuldest mir eine Robocopy -zeile... so lange hast Du in meinen Augen nix auf der Pfanne als Sprüche... ;)
zweite Variante...
Filtert wirklich nur die logdateien aus , welche am aktuellen Tag erstmals erstellt wurden, ...aber nicht die, welche nur geändert wurden... wie in Variante 1
Die Abfrage der speziellen Dateieigenschaften über das WMI ist Zeitaufwändig , und benötigt fast 3x so lange wie Variate 1.
dafür reduziert sich die Anzahl der ermittelten Dateien