CMD und die Normal- bzw. Sommerzeit
Hallo,
ich habe für mein Problem schon einige Zeit nach einer Lösung gesucht, aber noch nicht den richtigen Hinweis gefunden. Daher hoffe ich, dass mich hier noch jemand in die richtige Richtung "schubsen" kann.
Aktion
Ich sichere verschiedene Windows-PCs u.a. 1x im Monat als komplettes Image mit TrueImageHome. Zusätzlich kopiere ich diese monatlichen Backups auf eine zweite Festplatte und benenne sie dabei um, da ich dort weitere Auswahl-Operationen anhand des Dateinamens vollziehe. Das Ganze erledige ich mit einer CMD-Batch, da ich mich (leider) mit PowerShell noch nicht so richtig auskenne. Hier fehlt mir die Zeit für ein intensives Studium der Befehle.
Ich lese das Erstelldatum/Uhrzeit aus der Datei aus wenn diese Datei noch nicht am Ziel existiert, kopiere ich sie und benenne sie mit Datum/Uhrzeit im Dateinamen um.
Problem
Bekannterweise interpretiert CMD die Normal/Sommerzeit anders als Powershell und der Windows-Explorer:
=> Das Erstell/Änderungsdatum einer im Sommer erstellten/geänderten Datei wird im Winter (Normalzeit) eine Stunde eher angezeigt
=> PowerShell wiederum zeigt wie der Explorer jeweils die gleiche Uhrzeit zur Normalzeit und zur Sommerzeit an.
Wenn ich nun eine Datei, die im September erstellt wurde im September umbenenne erhalte ich:
2021-09-01_10-00_abc
Wenn ich die gleiche Datei dann noch einmal im November prüfe erhalte ich aber
2021-09-01_09-00_abc
Und wenn dann geprüft wird, ob die Datei schon im Ziel existiert, wird sie natürlich zusätzlich kopiert, da die Dateinamen unterschiedlich sind.
Status
So weit ich mich eingelesen habe, ist das ein Problem von CMD und ich grübele, wie ich das Problem umgehen könnte. Vermutlich muss ich die Sache anders angehen, um nicht auf die Eigenheit von CMD zu stoßen.
a) Wenn ich bei meinem Ansatz bleibe, müsste ich fortwährend prüfen, ob wir uns aktuell in der Normal/Sommerzeit befinden und wann die zu prüfende Datei erstellt wurde, um dann entsprechend die Uhrzeit zu korrigieren. Das ist machbar, aber auch mit viel Aufwand/Hirnschmalz verbunden.
b) Mein Backup-Programm kann Datum und Uhrzeit nicht (mehr) sinnvoll in den Dateinamen schreiben
c) Direkt nach dem Backup kann ich die Datei nicht umenennen, da dann das Backup-Programm durcheinander kommt und die Datei nicht wiederfindet. Daher mache ich das erst bei der Kopie auf ein weiteres Backupmedium
Das ist mein Codeschnipsel, der mein Problem verursacht:
Ich freue mich auf Ideen und Hinweise, wie ich das Ganze anders angehen könnte.
Vielen Dank,
SHC
ich habe für mein Problem schon einige Zeit nach einer Lösung gesucht, aber noch nicht den richtigen Hinweis gefunden. Daher hoffe ich, dass mich hier noch jemand in die richtige Richtung "schubsen" kann.
Aktion
Ich sichere verschiedene Windows-PCs u.a. 1x im Monat als komplettes Image mit TrueImageHome. Zusätzlich kopiere ich diese monatlichen Backups auf eine zweite Festplatte und benenne sie dabei um, da ich dort weitere Auswahl-Operationen anhand des Dateinamens vollziehe. Das Ganze erledige ich mit einer CMD-Batch, da ich mich (leider) mit PowerShell noch nicht so richtig auskenne. Hier fehlt mir die Zeit für ein intensives Studium der Befehle.
Ich lese das Erstelldatum/Uhrzeit aus der Datei aus wenn diese Datei noch nicht am Ziel existiert, kopiere ich sie und benenne sie mit Datum/Uhrzeit im Dateinamen um.
Problem
Bekannterweise interpretiert CMD die Normal/Sommerzeit anders als Powershell und der Windows-Explorer:
=> Das Erstell/Änderungsdatum einer im Sommer erstellten/geänderten Datei wird im Winter (Normalzeit) eine Stunde eher angezeigt
=> PowerShell wiederum zeigt wie der Explorer jeweils die gleiche Uhrzeit zur Normalzeit und zur Sommerzeit an.
Wenn ich nun eine Datei, die im September erstellt wurde im September umbenenne erhalte ich:
2021-09-01_10-00_abc
Wenn ich die gleiche Datei dann noch einmal im November prüfe erhalte ich aber
2021-09-01_09-00_abc
Und wenn dann geprüft wird, ob die Datei schon im Ziel existiert, wird sie natürlich zusätzlich kopiert, da die Dateinamen unterschiedlich sind.
Status
So weit ich mich eingelesen habe, ist das ein Problem von CMD und ich grübele, wie ich das Problem umgehen könnte. Vermutlich muss ich die Sache anders angehen, um nicht auf die Eigenheit von CMD zu stoßen.
a) Wenn ich bei meinem Ansatz bleibe, müsste ich fortwährend prüfen, ob wir uns aktuell in der Normal/Sommerzeit befinden und wann die zu prüfende Datei erstellt wurde, um dann entsprechend die Uhrzeit zu korrigieren. Das ist machbar, aber auch mit viel Aufwand/Hirnschmalz verbunden.
b) Mein Backup-Programm kann Datum und Uhrzeit nicht (mehr) sinnvoll in den Dateinamen schreiben
c) Direkt nach dem Backup kann ich die Datei nicht umenennen, da dann das Backup-Programm durcheinander kommt und die Datei nicht wiederfindet. Daher mache ich das erst bei der Kopie auf ein weiteres Backupmedium
Das ist mein Codeschnipsel, der mein Problem verursacht:
FOR /F "TOKENS=1,2,4 Delims= " %%a IN ('DIR /A-D /O-D /T:C %Backup_Quelle% ^| FINDSTR "Monat"') DO (
SET Jahr=%%a
SET Zeit=%%b
SETLOCAL EnableDelayedExpansion
SET TIH-Datei=!Jahr:~-4!-!Jahr:~-7,2!-!Jahr:~-10,2!_!Zeit:~0,2!-!Zeit:~3,2!_%%c
IF NOT EXIST %Backup_Ziel%\!TIH-Datei! (
ECHO.
ECHO ... %%c ...
ECHO. & ECHO.
ECHO - !TIH-Datei! >> %Temp1_SortBackups%
ROBOCOPY /NDL /NFL /MIR /FFT /DST %Backup_Quelle%\ %Backup_Ziel%\ %%c
REN %Backup_Ziel%\%%c !TIH-Datei!
ENDLOCAL)
)
Ich freue mich auf Ideen und Hinweise, wie ich das Ganze anders angehen könnte.
Vielen Dank,
SHC
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1477464365
Url: https://administrator.de/contentid/1477464365
Ausgedruckt am: 23.11.2024 um 12:11 Uhr
8 Kommentare
Neuester Kommentar
Moin,
ich würde da einen anderen Ansatz empfehlen: Prüfe nach File Hashes, ob dieser bereits in deinem Archiv existiert. Falls nicht, kopieren.
Der Dateiname ist dabei auch nicht relevant, sodass du das Benennungsproblem vollständig außen vor lassen kannst und die Dateien heißen können wie sie wollen.
Da würde ich aber tatsächlich zu Powershell raten, das geht damit deutlich einfacher.
So entgeht man auch dem Problem, sofern ein Kopiervorgang mal in die Hose gegangen ist. Dann stimmen die Hashes nicht und es wird neu kopiert.
Vg
ich würde da einen anderen Ansatz empfehlen: Prüfe nach File Hashes, ob dieser bereits in deinem Archiv existiert. Falls nicht, kopieren.
Der Dateiname ist dabei auch nicht relevant, sodass du das Benennungsproblem vollständig außen vor lassen kannst und die Dateien heißen können wie sie wollen.
Da würde ich aber tatsächlich zu Powershell raten, das geht damit deutlich einfacher.
So entgeht man auch dem Problem, sofern ein Kopiervorgang mal in die Hose gegangen ist. Dann stimmen die Hashes nicht und es wird neu kopiert.
Vg
Ich auch nicht.
Steffen
Bekannterweise interpretiert CMD die Normal/Sommerzeit anders als Powershell und der Windows-Explorer
Zwei Minuten Suchmaschine hilft. Wenn's nur um Erstellungsdatum und Dateiname geht, lässt sich auch ein PowerShell Aufruf in einen Batchcode packen, wenn du damit besser zurecht kommst.for /f "tokens=1*" %%i in (
'powershell -nop -ep Bypass -c "gci '%Backup_Quelle%' -filter '*Monat*' -file|sort CreationTime -descending|foreach{$_.CreationTime.ToString('yyyy-MM-dd_HH-mm_ ')+$_.Name}"'
) do (
echo %%i
echo "%%j"
echo ~~~~~
)
Steffen
Hallo,
mach das umbenennen zuerst direkt auf dem System auf dem du die Datei erzeugst.
Also Backup erzeugeund danach die Backup Datei umbenennen mit Datum (hier kannst Du dann auch direkt die Systemvariabeln verwenden).
Die Backupdatei dann kopieren und bereits existierende (gleicher Dateiname) überspringen. Das geht ja beim Kopierbefehl direkt per Parameter.
Ich dachte allerdings auch das TrueImageHome den Namen flexibel direkt mit dem aktuellen Datum (als Variable im Namen) erzeugen kann...
Gruß ...
mach das umbenennen zuerst direkt auf dem System auf dem du die Datei erzeugst.
Also Backup erzeugeund danach die Backup Datei umbenennen mit Datum (hier kannst Du dann auch direkt die Systemvariabeln verwenden).
Die Backupdatei dann kopieren und bereits existierende (gleicher Dateiname) überspringen. Das geht ja beim Kopierbefehl direkt per Parameter.
Ich dachte allerdings auch das TrueImageHome den Namen flexibel direkt mit dem aktuellen Datum (als Variable im Namen) erzeugen kann...
Gruß ...
Ich werde mir das in Ruhe ansehen und versuche zu verstehen, was der Befehl genau macht.
Ist genau das was im Kopf deiner FOR Schleife jetzt auch schon passiert, nur dass du deinen Zeitstempel schon formatiert bekommst.
gci '%Backup_Quelle%' -filter '*Monat*' -file
Get-ChildItem (alias gci) sucht im Pfad %Backup_Quelle%. Da das ganze in einem Batchcode ausgeführt wird, ersetzt die CMD die Variable durch den Wert bevor PowerShell aufgerufen wird.
Gefiltert wird nach Namen die
Monat
enthalten, die Sternchen sind Wildcards für "irgendwas oder nichts". Ist quasi das was dein nachgeschalteter FINDSTR Aufruf macht.Gesucht wird nur nach Dateien, nicht nach Verzeichnissen. Entspricht deiner Option /A-D für DIR.
|sort CreationTime -descending
Die gefundenen Dateiobjekte werden per Pipe an Sort-Object (alias sort) weitergegeben, die diese nach ihrer CreationTime Eigenschaft sortiert, und zwar absteigend. Entspricht deinen Optionen /T:C und /O-D für DIR.
|foreach{$_.CreationTime.ToString('yyyy-MM-dd_HH-mm_ ')+$_.Name
}Die sortierten Dateiobjekte werden per Pipe an ForEach-Object (alias foreach) weitergereicht. Die geschweiften Klammern sind dabei wie der Rumpf einer Schleife zu betrachten, bei der $_ in jedem Schleifendurchlauf je ein Dateiobjekt zugewiesen wird. Zuerst holen wir uns die CreationTime Eigenschaft des Objekts und formatieren sie in einen String, der auch gleich so aussieht wie du ihn für die neuen Dateinamen brauchst. Das nachgestellte Leerzeichen ist der Delimiter in der Batch FOR Schleife um den Inhalt von %%i und %%j voneinander zu trennen. Das + ist hier der Operator für Stringverkettung. Angehängt wird die Name Eigenschaft des Objekts. Das ganze ergib also einen String à la
2021-11-08_21-05_ Datei mit Monat im Name.ext
, der allein steht (nicht einer Variablen zugewiesen oder per Pipe weitergeleitet wird). Somit wird er implizit als neue Zeile in die Ausgabe geschrieben.Das Ganze wird per PowerShell ausgeführt und die Ausgabe wird durch die Batch FOR Schleife zeilenweise gelesen. Das
"tokens=1*"
sorgt dafür, dass der erste durch Leerzeichen getrennte Teilstring in %%i landet, der ganze Rest (egal ob weitere Leerzeichen vorhanden sind) in %%j.That's it.
Steffen