mac1972
Goto Top

Dateien nach Erstelldatum (Jahr) in Ordner verschieben aber nur wenn älter n-Tage (länderübergreifend in Bezug auf Auswertung Datum)

Hallo zusammen,

über ein Script sollen Dateien nach Erstelldatum in Ordner (Jahr "YYYY" wäre ausreichend) verschoben werden.
Die zu verschiebenden Dateien können unterschiedliche Extensions besitzen (.xml, .txt, .pdf ggf. noch weitere) und befinden sich "schlimmstenfalls" noch in weiteren Unterordnern der Quelle. Erschwerend kommt hinzu, dass NUR Dateien älter 90 Tage (ab Erstelldatum) tatsächlich verschoben werden sollen. Zudem kann mit %date% nicht ohne weiteres das Datum ermittelt werden, da das Script länderübergreifend mit unterschiedlichen Datums- und Regionseinstellungen zurecht kommen müsste.

Über die Forensuche habe ich hierzu einen alten Vorschlag von "Bastla" gefunden und diesen geringfügig angepasst (bin hier absoluter Anfänger auf dem Gebiet der Batch-Programmmierung). Der Script-Entwurf läuft mit einem "move"-Befehl und funktioniert grundlegend wie unten gelistet, jedoch mit Ausnahme des "älter-als-Kriteriums" - ich habe keine Idee wie ich das einbauen könnte. Versuche den "Move" mit Robocopy (Minage:90) zu ersetzen haben nicht richtig funktioniert (zumindest nicht in der Schleife mit den Unterordnern).

Hätte jemand eine Lösung zu diesem Problem?

- nicht vorhandene Jahresordner sollen erstellt werden
- Quelldateien können sich auch in Unterordnern der Quelle befinden
- Quelldateien können unterschiedliche Extensions haben, beste Variante wäre hier wohl: *.*
- Script müsste länderübergreifend funktionieren, falls ein Datumsvergleich notwendig wäre
- Datei-Duplikate dürfen direkt überschrieben werden
- Es sollen nur Files älter 90 Tage (oder n-Tage) verschoben werden
- Quelle = Ziel

Vielen Dank im Voraus.
Gruß,
MAC1972


@echo off 
set "quelle=C:\Test"   
set "ziel=C:\Test"   

:: Verschieben in der Route
pushd "%quelle%"   
for /f "tokens=1-5* delims=. " %%a in ('dir /tc /-c *.txt *.xml *.pdf 2^>nul ^|findstr /i /e "\.txt \.xml \.pdf"') do (   
    md "%ziel%\%%c" 2>nul   
    move "%%f" "%ziel%\%%c\"  
) 
popd

:: Verschieben inkl. Unterverzeichnisse
for /f "delims=" %%i in ('dir /s /b /ad "%quelle%"') do (   
    pushd "%%i"   
    for /f "tokens=1-5* delims=. " %%a in ('dir /tc /-c *.txt *.xml *.pdf 2^>nul ^|findstr /i /e "\.txt \.xml \.pdf"') do (   
        md "%ziel%\%%c" 2>nul   
        move "%%f" "%ziel%\%%c\"  
    ) 
    popd 
)

Content-Key: 333134

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

Ausgedruckt am: 19.03.2024 um 09:03 Uhr

Mitglied: rubberman
rubberman 24.03.2017 aktualisiert um 17:55:34 Uhr
Goto Top
Hallo MAC1972

Solange du das nicht zwingend mit einem Batchscript erledigen musst, findet sich sicher ein Weg. Mindestens dein "länderübergreifend" wäre sonst das Ausschlusskriterium, es sei denn du kannst robocopy verwenden. (Selbst da wäre das Herausfinden des Jahrs immer noch ein Problem.) Sind die Windowsversionen einigermaßen aktuell?

Grüße
rubberman
Mitglied: 132692
Lösung 132692 24.03.2017 aktualisiert um 18:13:42 Uhr
Goto Top
Wenns Windows ist würde ich gleich auf Powershell umsteigen.
Das sich die Leute immer noch mit diesen Batchunzulänglichkeiten rumschlagen bleibt mir ein Rätsel, wenn Windows doch so schöne Skriptsprachen mitbringt.
$source = 'D:\Daten'  
$target = 'D:\oldfiles'  
$days = 90
gci $source -Recurse | ?{!$_.PSIContainer -and $_.CreationTime -lt (get-date).AddDays(-$days)} | %{
        $targetdir = "$target\$($_.CreationTime.Year)$($_.DirectoryName.replace($source,''))"  
        if(!(Test-Path $targetdir)){md $targetdir | out-null}
        move-item $_.FullName -Destination $targetdir -Force -Verbose
}
Gruß p.
Mitglied: MAC1972
MAC1972 24.03.2017 um 18:27:18 Uhr
Goto Top
Hallo,
Danke für die Antworten.
Auf allen Clients läuft Win7 x86.

Hiermit lässt sich ein länderübergreifender Zeitstempel erstellen - das funktioniert:

:: ***** GET TIMESTAMP VIA WMIC  ********************************************************************************
FOR /f %%i in ('WMIC OS GET LocalDateTime /value') DO FOR /f "tokens=2 delims==" %%j in ("%%i") DO SET "ldt=%%j"  
SET "timestamp=%ldt:~,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%"  

Robocopy wäre auch eine Möglichkeit.
Ich probiere später in jedem Fall parallel die Powershell-Lösung.

Danke und Gruß,
MAC1972
Mitglied: 132692
132692 24.03.2017 aktualisiert um 18:54:51 Uhr
Goto Top
Zitat von @MAC1972:
Hiermit lässt sich ein länderübergreifender Zeitstempel erstellen - das funktioniert:
Das ist klar , das ist aber das aktuelle Datum und nicht das der Datei.
Das kannst du auch über die Regionseinstellungen aus der Registry auslesen, entweder mit einem VBS oder per Batch
for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v iDate') do set iDate=%%a  
for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sDate') do set sDate=%%a  

if %iDate%==0 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ("%date%") DO SET Year=%%C  
if %iDate%==1 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ("%date%") DO SET Year=%%C  
if %iDate%==2 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ("%date%") DO SET Year=%%A  
In Batch ist das schon machbar, ob es den Aufwand für den Zweck wert ist ist dann eine andere Frage. Muss jeder selbst entscheiden.

Man kann auch in Batch mit Datumswerten Regionsunabhängig rechnen wenn man will, wie immer nur viel Schreibaufwand für "nügs":
@echo off
call :AddDays %date% -2 newDate
echo %newDate%

goto :eof
::===========================================================================
:: Subroutines: Datum berechnen
:: Parameter 1: Datum im lokalen Format
:: Parameter 2: Anzahl Tage die addiert oder subtrahiert werden sollen
:: Parameter 3: Variable welcher das berechnete Datum zugewiesen werden soll
::===========================================================================
:AddDays
set "DaysToAdd=%~2"  

for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v iDate') do set iDate=%%a  
for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sDate') do set sDate=%%a  

if %iDate%==0 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%~1') DO (  
	SET GYear=%%C
	SET GMonth=%%A
	SET GDay=%%B
)
if %iDate%==1 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%~1') DO (  
	SET GYear=%%C
	SET GMonth=%%B
	SET GDay=%%A
)
if %iDate%==2 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%~1') DO (  
	SET GYear=%%A
	SET GMonth=%%B
	SET GDay=%%C
)

IF %GMonth:~0,1% EQU 0 SET GMonth=%GMonth:~1%
IF %GDay:~0,1% EQU 0 SET GDay=%GDay:~1%
SET /A GMonth1= ( %GMonth% - 14 ) / 12
SET /A GYear1= %GYear% + 4800
SET /A JDate= 1461 * ( %GYear1% + %GMonth1% ) / 4 + 367 * ( %GMonth% - 2 -12 * %GMonth1% ) / 12 - ( 3 * ( ( %GYear1% + %GMonth1% + 100 ) / 100 ) ) / 4 + %GDay% - 32075
if "%DaysToAdd:~0,1%" == "-" (set /a JDate-=%DaysToAdd:~1%) else (set /a JDate+=%DaysToAdd%)  

SET /A P= %JDate% + 68569
SET /A Q= 4 * %P% / 146097
SET /A R= %P% - ( 146097 * %Q% +3 ) / 4
SET /A S= 4000 * ( %R% + 1 ) / 1461001
SET /A T= %R% - 1461 * %S% / 4 + 31
SET /A U= 80 * %T% / 2447
SET /A V= %U% / 11
SET /A GYear=100 * ( %Q% - 49 ) + %S% + %V%
SET /A GMonth=%U% + 2 - 12 * %V%
SET /A GDay=%T% - 2447 * %U% / 80
IF 1%GMonth% LSS 20 SET GMonth=0%GMonth%
IF 1%GDay% LSS 20 SET GDay=0%GDay%
set %~3=%GYear%-%GMonth%-%GDay%
Goto :EOF

Und per VBS in einer BATCH kommst du auch an das Jahr
@echo off
echo wscript.echo Year(CreateObject("Scripting.FileSystemObject").GetFile(wscript.Arguments(0)).DateCreated) >"%temp%\year.vbs"  
cscript //NOLOGO "%temp%\year.vbs" "C:\testdatei.txt" 
Du hast also die Qual der Wahl für dein Skript face-smile, jetzt hast du alles was du brauchst, musst es nur noch zusammensetzen. Denke das ist eine schöne Aufgabe für dich für's Wochenende face-wink.
Mitglied: rubberman
rubberman 24.03.2017 um 18:55:52 Uhr
Goto Top
ob es den Aufwand für den Zweck wert ist
Nein. Wenn nicht PS, bist du mit VBS oder JS immer noch besser bedient. Die Ausgabe von DIR zu parsen geht am Ende in die Hose. Die Anzahl Tokens ist abhängig vom 12 oder 24 Stunden Zeitformat (wegen AM/PM). Viel zu kompliziert, das alles mit einzubeziehen ...

Grüße
rubberman
Mitglied: MAC1972
MAC1972 28.03.2017 um 18:10:28 Uhr
Goto Top
Hallo zusammen,
Danke für die Inputs und Antworten.
Entscheide mich für die Powershell-Lösung - diese funktioniert wie gewünscht (versuche mich hier einzuarbeiten).

Danke und Gruß,
MAC1972