tomreis
Goto Top

Bild- und Videodateien per Batch nach Namen und Attributen ins richtige Verzeichnis verschieben oder löschen

Hallo an alle,

ich habe folgende Aufgabe zu lösen:

Es gibt ein Quellverzeichnis "D:\Ablage" wo zahlreiche Bild- & Videodateien mit dem Format: '2018-05-25 13.38.36.*' (*=jpg o. avi o. mpg usw.) abgelegt sind.

Weiterhin gibt es ein Zielverzeichnis "Z:\Foto" mit folgender Verzeichnisstruktur

• 2018
• 01
• 02
• 03
• 04
usw. bis 12

• 2019
• 01
• 02
• 03
• 04
usw. bis 12

also für jedes Jahr.

Nun möchte ich die Dateien aus der Quelle passen zum beginnenden Dateiname "z.B. 2018-05" in das jeweils richtige Monatsverzeichnis des dazugehörigen Jahres VERSCHIEBEN !

Dabei soll geprüft werden, ob die Datei ev. schon vorhanden ist. Ist am Ziel bereits eine passende Datei vorhanden, soll diese, wenn Sie kleiner ist als die Quelldatei, überschrieben werden.
Ist sie gleich oder größer als die Quelldatei soll die Quelldatei nicht verschoben werden, sondern in der Quelle gelöscht werden.

Ziel ist es also das Quellverzeichnis zu leeren und die Quelldateien auf die jeweiligen Jahresverzeichnisse des Zieles, monatsconform, zu verteilen.
Dabei sollen aber nur bereits kleinere vorhandene Dateien überschrieben werden. Ev. größere vorhandene Dateien sollen bestehen bleiben.

Ein Highlight wäre natürlich, wenn der Batch prüft ob es im Zielverzeichnis bereits das passende Jahresverzeichnis und darin das passende Monatsunterverzeichnis vorhanden ist und wenn nicht, es einfach anlegt face-smile das muss aber nicht sein face-smile

Ich hoffe ich habe mein Vorhaben bestmöglich verdeutlicht und wäre für Hilfen sehr dankbar !!!

Grüße und Dank Tom

Content-Key: 561993

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

Ausgedruckt am: 29.03.2024 um 00:03 Uhr

Mitglied: 143127
143127 31.03.2020 aktualisiert um 10:14:15 Uhr
Goto Top
Würde ich zwar gleich mit nem Powershell Einzeiler abfackeln aber wenn du es unbedingt kryptisch magst face-smile
@echo off &setlocal
set "quelle=D:\Ablage"  
set "ziel=Z:\Foto"  
for %%a in ("%quelle%\*.*") do (  
    for /f "tokens=1,2 delims=-" %%b in ("%%~na") do (  
        if not exist "%ziel%\%%~b\%%~c" md "%ziel%\%%~b\%%~c" >nul  
        if not exist "%ziel%\%%~b\%%~c\%%~nxa" move "%%a" "%ziel%\%%~b\%%~c"  
    )
)
Mitglied: tomreis
tomreis 31.03.2020 um 09:44:43 Uhr
Goto Top
Du bist mein Traum !!!!!! Vielen lieben Dank - abschließend - wie würde denn der Powershell Einzeiler aussehen ??? face-smile LG Tom
Mitglied: tomreis
tomreis 31.03.2020 um 09:59:12 Uhr
Goto Top
Hey vibrations, ich habe bei Deinem Batch gerade festgestellt, dass die Größenprüfung nicht funktioniert oder nicht vorhanden ist. Heist: wenn in der Quelle eine Datei 1.jpg (mit 150 kb) ist und die gleiche Datei bereits mit identischem Namen am Ziel existiert, dort aber (300kb hat) wird die größere Datei am Ziel trotzdem überschrieben. Das ist ungewollt face-smile Gibt es dafür noch eine Lösung ? LG Tom
Mitglied: 143127
143127 31.03.2020 aktualisiert um 10:16:16 Uhr
Goto Top
dass die Größenprüfung nicht funktioniert oder nicht vorhanden ist.
Hat je keiner gefordert .... s. Code oben.
Mitglied: tomreis
tomreis 31.03.2020 um 10:18:05 Uhr
Goto Top
sorry hatte ich geschrieben:

"Dabei sollen aber nur bereits kleinere vorhandene Dateien überschrieben werden. Ev. größere vorhandene Dateien sollen bestehen bleiben."

Hätte ich vielleicht etwas mehr kennzeichnen müssen face-sad
Mitglied: 143127
143127 31.03.2020 aktualisiert um 10:59:36 Uhr
Goto Top
wie würde denn der Powershell Einzeiler aussehen ??? LG Tom
gci "d:\Ablage" -File | group {[regex]::match($_.Basename,'\d{4}-\d{2}').Value} | %{$ziel = "Z:\Ziel\$($_.Name.replace('-','\')"; md $ziel -EA SilentlyContinue | out-null; $_.Group | move-item -Destination $ziel -EA SilentlyContinue }  

edit - Für die Größenunterscheidung dann
gci "d:\Ablage" -File | ?{$_.Basename -match '\d{4}-\d{2}'} | %{  
    $ziel = "Z:\Foto\$($matches.replace('-','\'))"  
    if (!(Test-Path $ziel)){md $ziel -Force | out-null}
    $dfile = "$ziel\$($_.Name)"  
    if (((get-item $dfile -EA SilentlyContinue).Length -gt $_.Length) -or !(Test-Path $dfile)){
        $_ | move-item -Destination $ziel -Force
    }
}
Mitglied: tomreis
tomreis 31.03.2020 um 11:21:03 Uhr
Goto Top
vielen lieben Dank für Deine Mühen !!! ich benutzte jetzt zu Testzwecken folgende Variante:

gci "d:\Quellestart" -File | ?{$_.Basename -match '\d{4}-\d{2}'} | %{  
    $ziel = "d:\Quelleziel\$($matches.replace('-','\'))"  
    if (!(Test-Path $ziel)){md $ziel -Force | out-null}
    $dfile = "$ziel\$($_.Name)"  
    if (((get-item $dfile -EA SilentlyContinue).Length -gt $_.Length) -or !(Test-Path $dfile)){
        $_ | move-item -Destination $ziel -Force
    }
}

Wenn das Zielverzeichnis nicht vorhanden ist, funktioniert das ganze einwandfrei. Zielverzeichnisse werden angelegt und Dateien verschoben. Quellordner ist danach leer.

Haben wir aber schon im Ziel die passende Verzeichnisstruktur und im Monat 05 z.B. schon zwei Dateien (eine gross eine klein) werden die beiden gleichnamigen Dateien im Quellverzeichniss werder kopiert, verschoben oder gelöscht. Das Script läuft aber ohne Fehlermeldung - alles bleibt wie es ist ???
Mitglied: TK1987
TK1987 31.03.2020 um 16:45:16 Uhr
Goto Top
Moin,

Zitat von @tomreis:
Haben wir aber schon im Ziel die passende Verzeichnisstruktur und im Monat 05 z.B. schon zwei Dateien (eine gross eine klein) werden die beiden gleichnamigen Dateien im Quellverzeichniss werder kopiert, verschoben oder gelöscht. Das Script läuft aber ohne Fehlermeldung - alles bleibt wie es ist ???
einfach noch eine Else-Anweisung anhängen.
gci "d:\Quellestart" -File | ?{$_.Basename -match '\d{4}-\d{2}'} | %{  
    $ziel = "d:\Quelleziel\$($matches.replace('-','\'))"  
    if (!(Test-Path $ziel)){md $ziel -Force | out-null}
    $dfile = "$ziel\$($_.Name)"  
    if (((get-item $dfile -EA SilentlyContinue).Length -gt $_.Length) -or !(Test-Path $dfile)){
        $_ | move-item -Destination $ziel -Force
    } else {rm $_}

}

Gruß Thomas
Mitglied: tomreis
tomreis 31.03.2020 um 20:53:54 Uhr
Goto Top
Hallo Thomas,

ich habe die Else Anweisung eingebaut (DANKE !).

Sofern sich das zu startende .ps1 Script in dem betreffenden "d:\quellestart" befindet und von dort aus gestartet wird, werden die vorhandenen Dateien nach dem Ausführen gelöscht.

Starte ich es z.B. von c:\ dann kommt eine Fehlermeldung, dass das Script die betreffende Bilddatei nicht auf c:\ finden konnte.

Jedoch muss darüber hinaus noch ein "Feature" face-smile in dem Script sein.

Denn sofern schon am Ziel Dateien mit gleichen Namen vorhanden sind, werden diese weder geändert noch überschrieben - es wird quasi nichts von dem Script ausgeführt - außer mit der Else-Anweisung - ggf. die Dateien im Quellverzeichniss gelöscht (sh. oben). Hast Du da ev. noch eine Lösung ???

Wie gesagt, sind die betreffenden Dateien am Ziel noch nicht vorhanden, werden die Dateien normal kopiert und wohl dank der ELSE in der Quelle gelöscht.

Gruss Tom
Mitglied: TK1987
TK1987 01.04.2020 um 10:40:36 Uhr
Goto Top
Zitat von @tomreis:
Starte ich es z.B. von c:\ dann kommt eine Fehlermeldung, dass das Script die betreffende Bilddatei nicht auf c:\ finden konnte.
In dem Fall muss die Else-Anweisung dann
else {rm $_.FullName}
lauten.
Denn sofern schon am Ziel Dateien mit gleichen Namen vorhanden sind, werden diese weder geändert noch überschrieben - es wird quasi nichts von dem Script ausgeführt - außer mit der Else-Anweisung - ggf. die Dateien im Quellverzeichniss gelöscht (sh. oben). Hast Du da ev. noch eine Lösung ???
Öhm... genau das wolltest du doch auch so haben?! Sofern die Datei in dem Ziel vorhanden ist, wird geprüft, ob diese Größer als die Datei aus der Quelle ist. Wenn die Datei im Ziel also größer ist, passiert dort auch nichts.
Mitglied: tomreis
tomreis 01.04.2020 um 15:17:34 Uhr
Goto Top
Ja nur leider werden kleiner vorhandene nicht durch etwaige größere, gleichnamige aus der Quelle überschrieben !
Mitglied: tomreis
tomreis 01.04.2020 um 15:30:46 Uhr
Goto Top
ahhh - ich habe den Fehler gefunden - kann ihn aber nicht selbst ändern face-sad

Das Script arbeitet genau verkehr herum.

Es überschreibt größere Dateien am Ziel mit einer kleineren Quelldatei. Es muss aber genau umgekehrt sein face-smile wo stelle ich das ein bzw. richtig ???

LG und Dank Tom

gci "d:\Quellestart" -File | ?{$_.Basename -match '\d{4}-\d{2}'} | %{  
    $ziel = "d:\Quelleziel\$($matches.replace('-','\'))"  
    if (!(Test-Path $ziel)){md $ziel -Force | out-null}
    $dfile = "$ziel\$($_.Name)"  
    if (((get-item $dfile -EA SilentlyContinue).Length -gt $_.Length) -or !(Test-Path $dfile)){
        $_ | move-item -Destination $ziel -Force
    } else {rm $_}
}
Mitglied: TK1987
TK1987 01.04.2020 aktualisiert um 16:24:34 Uhr
Goto Top
Zitat von @tomreis:
Es überschreibt größere Dateien am Ziel mit einer kleineren Quelldatei.
Jetzt wo du's sagst
wo stelle ich das ein bzw. richtig ???
gci "d:\Quellestart" -File | ?{$_.Basename -match '\d{4}-\d{2}'} | %{  
     $ziel = "d:\Quelleziel\$($matches.replace('-','\'))"  
     if (!(Test-Path $ziel)){md $ziel -Force | out-null}
     $dfile = "$ziel\$($_.Name)"  
     if (((get-item $dfile -EA SilentlyContinue).Length -le $_.Length) -or !(Test-Path $dfile)){
         $_ | move-item -Destination $ziel -Force
     } else {rm $_.FullName}
 }
Mitglied: tomreis
tomreis 01.04.2020 um 17:38:08 Uhr
Goto Top
Vielen lieben Dank - und Dank an alle die geholfen haben - so ist es wie ich es benötige / SUPI !!!!!