Batch soll 2 Dateien suchen, wenn vorhanden die gefundene aus einem Ordner kopieren
hi, ich bastel hier schon ein paar Tage dran herum, also immer mal wieder. So ganz funktioniert das nie, wie ich das möchte.
Strukur ist folgende:
Batch-Ort: Hauptordner\#Im
Hauptordner\#Im\GB\
dort sind 2 Dateien enthalten: wasser.txt & wasser2.txt und noch weitere Dateien und Ordner.
Der Gesamte Hauptordner samt Unterordnern außer dem #Im-Ordner soll nun nach wasser.txt & wasser2.txt durchsucht werden.
1. Es soll wenn wasser.txt gefunden wird der Inhalt des GB-Ordners kopiert werden in den Ordner mit der wasser.txt. Dabei können mehrere Ordner eine wasser.txt enthalten. ->gleiches gilt für die wasser2.txt
2. Zuvor soll aber die wasser.txt als wasser.txt_sic gesichert werden, die in dem jeweiligen Ordner gefunden wurde. Wenn bereits eine wasser.txt_sic vorhanden ist soll sie als wasser.txt_sic2 gesichert werden. Also wenn ich die batch 5x ausführe, dann wird in Zukunft die gefundene wasser.txt immer als wasser.txt_sic2 gesichert und die wasser.txt_sic nur beim 1. Mal verwendet als Sicherungsname. -> gleiches gilt für die wasser2.txt
3. Soweit hatte ich das alles schon hinbekommen. Jetzt kommt allerdings eine Einschränkung für Schritt 1. Hier soll der gesamte Ordner außer einer der beiden Dateien wasser.txt und wasser2.txt, nämlich die nicht gefunden wurde kopiert werden. Also am Beispiel:
Hauptordner\Daten1\wasser2.txt wird gefunden
Hauptordner\Daten1\wasser.txt existiert nicht
Jetzt soll die gefundene wasser2.txt als wasser2.txt_sic2 gespeichert werden, da dort auch eine wasser2.txt_sic bereits vorhanden ist.
Danach soll der Ordnerinhalt #Im\GB in den gefundenen Ordner: Hauptordner\Daten1 kopiert werden. Aber Achtung! Nicht die wasser.txt, weil diese nicht in dem Ordner existiert in dem Beispiel.
Das ist mein bester Versuch, irgendwo hapert es aber:
Ich hoffe Jemand kann da etwas Licht ins Dunkel bringen. Danke schon einmal!
Strukur ist folgende:
Batch-Ort: Hauptordner\#Im
Hauptordner\#Im\GB\
dort sind 2 Dateien enthalten: wasser.txt & wasser2.txt und noch weitere Dateien und Ordner.
Der Gesamte Hauptordner samt Unterordnern außer dem #Im-Ordner soll nun nach wasser.txt & wasser2.txt durchsucht werden.
1. Es soll wenn wasser.txt gefunden wird der Inhalt des GB-Ordners kopiert werden in den Ordner mit der wasser.txt. Dabei können mehrere Ordner eine wasser.txt enthalten. ->gleiches gilt für die wasser2.txt
2. Zuvor soll aber die wasser.txt als wasser.txt_sic gesichert werden, die in dem jeweiligen Ordner gefunden wurde. Wenn bereits eine wasser.txt_sic vorhanden ist soll sie als wasser.txt_sic2 gesichert werden. Also wenn ich die batch 5x ausführe, dann wird in Zukunft die gefundene wasser.txt immer als wasser.txt_sic2 gesichert und die wasser.txt_sic nur beim 1. Mal verwendet als Sicherungsname. -> gleiches gilt für die wasser2.txt
3. Soweit hatte ich das alles schon hinbekommen. Jetzt kommt allerdings eine Einschränkung für Schritt 1. Hier soll der gesamte Ordner außer einer der beiden Dateien wasser.txt und wasser2.txt, nämlich die nicht gefunden wurde kopiert werden. Also am Beispiel:
Hauptordner\Daten1\wasser2.txt wird gefunden
Hauptordner\Daten1\wasser.txt existiert nicht
Jetzt soll die gefundene wasser2.txt als wasser2.txt_sic2 gespeichert werden, da dort auch eine wasser2.txt_sic bereits vorhanden ist.
Danach soll der Ordnerinhalt #Im\GB in den gefundenen Ordner: Hauptordner\Daten1 kopiert werden. Aber Achtung! Nicht die wasser.txt, weil diese nicht in dem Ordner existiert in dem Beispiel.
Das ist mein bester Versuch, irgendwo hapert es aber:
@echo off
setlocal enabledelayedexpansion
set "sourceDir=%~dp0GB"
set "searchFile1=wasser.txt"
set "searchFile2=wasser2.txt"
REM Gehe alle Ordner ein Verzeichnis höher als #Im durch
for /f "delims=" %%A in ('dir /s /b /a-d "%~dp0..\%searchFile1%" ^| find /v "%~dp0"') do (
set "dir=%%~dpA"
REM Überprüfen, ob wasser.txt existiert
if exist "%%A" (
REM Wenn die _sic-Datei existiert, erstelle _sic2 (Überschreiben)
if exist "!dir!wasser.txt_sic" (
copy "%%A" "!dir!wasser.txt_sic2" /Y
) else (
REM Wenn die _sic-Datei nicht existiert, erstelle sie
copy "%%A" "!dir!wasser.txt_sic" /Y
)
)
REM Überprüfen, ob wasser2.txt existiert
if exist "%%A" (
REM Wenn die _sic-Datei existiert, erstelle _sic2 (Überschreiben)
if exist "!dir!wasser2.txt_sic" (
copy "%%A" "!dir!wasser2.txt_sic2" /Y
) else (
REM Wenn die _sic-Datei nicht existiert, erstelle sie
copy "%%A" "!dir!wasser2.txt_sic" /Y
)
)
REM Kopieren des GB-Ordners nach !dir!
REM Überprüfen, ob die Dateien wasser.txt oder wasser2.txt vorhanden sind
if exist "!dir!wasser.txt" (
xcopy /E /I /Y "%sourceDir%\*" "!dir!" /EXCLUDE:wasser2.txt >nul 2>&1
)
if exist "!dir!wasser2.txt" (
xcopy /E /I /Y "%sourceDir%\*" "!dir!" /EXCLUDE:wasser.txt >nul 2>&1
)
)
pause
exit
Ich hoffe Jemand kann da etwas Licht ins Dunkel bringen. Danke schon einmal!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 671723
Url: https://administrator.de/forum/batch-soll-2-dateien-suchen-wenn-vorhanden-die-gefundene-aus-einem-ordner-kopieren-671723.html
Ausgedruckt am: 06.03.2025 um 20:03 Uhr
5 Kommentare
Neuester Kommentar
Moin Julia,
nach der Wasser.txt hast du ja in der For-Schleife bereits gesucht, diese existiert an der Stelle also immer und die Überprüfung ist somit überflüssig.
verstehe ich an der Stelle nicht. %%A ist hier ja die Wasser.txt und nicht die Wasser2.txt. Du müsstest die Schleife ein weiteres mal starten und diesmal statt der Wasser.txt nach der Wasser2.txt suchen.
Um den Code nicht doppelt schreiben zu müssen, verwendest du dann am besten eine Funktion und übergibst die Dateinamen an diese. Zudem zum Kopieren besser Robocopy statt Xcopy nutzen.
Hier das Ganze mal alternativ iin Powershell, die Wahl liegt bei dir...
Gruß Thomas
nach der Wasser.txt hast du ja in der For-Schleife bereits gesucht, diese existiert an der Stelle also immer und die Überprüfung ist somit überflüssig.
REM Überprüfen, ob wasser2.txt existiert
if exist "%%A" (
Um den Code nicht doppelt schreiben zu müssen, verwendest du dann am besten eine Funktion und übergibst die Dateinamen an diese. Zudem zum Kopieren besser Robocopy statt Xcopy nutzen.
@echo off
setlocal EnableDelayedExpansion
set "sourceDir=%~dp0GB"
REM <filename> <excludeFilename>
call :searchFile "wasser.txt" "wasser2.txt"
call :searchFile "wasser2.txt" "wasser.txt"
pause
exit /b 0
:searchFile <filename> <excludeFilename>
REM Gehe alle Ordner ein Verzeichnis höher als #Im durch
for /f "delims=" %%A in ('dir /s /b /a-d "%~dp0..\%~1" ^| find /v "%~dp0"') do (
set "dir=%%~dpA\"
REM Wenn die _sic-Datei existiert, erstelle _sic2 (Überschreiben)
if exist "!dir!%~1_sic" (
copy "%%A" "!dir!%~1_sic2" /Y
) else (
REM Wenn die _sic-Datei nicht existiert, erstelle sie
copy "%%A" "!dir!%~1_sic" /Y
)
REM Kopieren des GB-Ordners nach !dir!, <excludeFilename> ausschließen
>nul 2>&1 robocopy "%sourceDir%" "!dir!" /E /XF "%~2"
)
REM Ende der Funktion
exit /b 0
Jo, danke ich hab von Powershell so gar keine Ahnung.
Eigentlich ist die Powershell-Syntax viel leicht verständlicher als die von cmd. Gerade wenn das Vorhaben mal etwas Umfangreicher wird, wird Batch auch für das geübte Auge schnell sehr unübersichtlich - von den ganzen Fallstricken und Bugs mal garnicht zu sprechen.Hier das Ganze mal alternativ iin Powershell, die Wahl liegt bei dir...
$sourceDir = "$PsScriptRoot\GB"
$rootDir = (Get-Item $PsScriptRoot).Parent.FullName
$searchFiles = @(
"Wasser.txt"
"Wasser2.txt"
)
# Suche im Rootverzeichnis nach $searchFiles (Skriptverzeichnis ausgenommen)
foreach ($file in Get-ChildItem -Recurse -File -Path $rootDir -Include $searchFiles | Where FullName -NotLike "$PsScriptRoot\*") {
# Wenn _sic existiert, _sic2 erstellen bzw. überschreiben. Sonst _sic erstellen
if (Test-Path ($file.FullName + "_sic")) { copy -Path $file -Destination ($file.FullName + "_sic2") }
else { copy -Path $file -Destination ($file.FullName + "_sic") }
# Kopiere Daten aus Quellordner, schließe alle Dateinamen aus $searchFiles ausser der gefundenen Datei selbst aus.
copy -Recurse -Path "$sourceDir\*" -Destination $file.DirectoryName -Exclude ($searchFiles -ne $file.Name)
}
Gruß Thomas
Zitat von @o0Julia0o:
Mal kurz ps1 und Batch miteinander verglichen:
ps1:
64 Wörter
474 Zeichen (ohne Leerzeichen)
Hierzu sei gesagt, dass ich dieses Powershell-Skript, weil Anfängergerechter, sehr ausführlich geschrieben habe.Mal kurz ps1 und Batch miteinander verglichen:
ps1:
64 Wörter
474 Zeichen (ohne Leerzeichen)
Man kann da...
- einige Parameter einfach weglassen ("-Path" z.B. fast immer)
- andere einfach kürzen (z.B. statt "-Recurse" einfach "-R")
- viele Befehle durch kurze Aliase ersetzen (z.B. statt "Get-ChildItem" einfach "gci", "ls" oder "dir").
Das geht also auch noch mit deutlich weniger Wörtern und Zeichen.
Wobei ich denke, dass für nicht so Clevere Batch eher geeignet ist, da es eher sich an der gesprochenen Sprache orientiert.
Das sehe ich genau anders herum.Wer noch nie mit sowas gearbeitet hat, kann den Powershell Code vom reinen lesen eher verstehen.
Bei Batch wird der Code durch die vielen Prozentzeichen und Parameter, deren Bedeutung man erst kennen muss, schnell abstrakt.
ps1 muss aber aufwändig gestartet werden
Geht doch mittlerweile leicht über das Kontextmenü (Rechtsklick > Mit Powershell ausführen). Aber zugegeben, Doppelklick ist einfacher - das geht hier nur mittels Verknüpfung.ps1 funkioniert nach Umwandlung zur exe nicht mehr(Batch aber auch nicht))
Doch, Powershell Skripte funktionieren als exe umgewandelt.Geht das mit der Batch nicht auch effektiver?
Leider nein.