Dateien in verschiedene Ordner kopieren
Hallo liebe Community,
Ich bin auf dem Gebiet von Batch ein totaler Neuling und kenn mich überhaupt nicht aus.
Deswegen bitte ich euch um Rat.
Nun zu meinem Problem.
Ich möchte via Batch Dateien auf ein anderes Laufwerk in verschiedene Ordner kopieren. Falls die Datei schon vorhanden ist soll diese im namen eweitert werden, sodass ich beide Dateien behalte.
Die Dateinamen sehen wie folgt aus:
3413_13354789.pdf
20501_55568749.pdf
4403_....
etc.
Ausgangsorder ist der windows "eigene dateien/myscans/" ordner und ziellaufwerk ein usb-stick.
Auf dem USB-Stick sind jeweis Ordner mit der mit der Bezeichnung "3413", "20501","4403" etc.
Also, ich möchte alle Dateien, die mit der Zahl vor dem Unterstrich anfangen, in den jeweils dazugehörigen Ordner verschieben. Falls dieser noch nicht existiert soll einer erstellt werden.
Ich hoffe ich habe mein Vorhaben verständnisvoll geschildert.
Vielen Dank schon mal im voraus !
Ich bin auf dem Gebiet von Batch ein totaler Neuling und kenn mich überhaupt nicht aus.
Deswegen bitte ich euch um Rat.
Nun zu meinem Problem.
Ich möchte via Batch Dateien auf ein anderes Laufwerk in verschiedene Ordner kopieren. Falls die Datei schon vorhanden ist soll diese im namen eweitert werden, sodass ich beide Dateien behalte.
Die Dateinamen sehen wie folgt aus:
3413_13354789.pdf
20501_55568749.pdf
4403_....
etc.
Ausgangsorder ist der windows "eigene dateien/myscans/" ordner und ziellaufwerk ein usb-stick.
Auf dem USB-Stick sind jeweis Ordner mit der mit der Bezeichnung "3413", "20501","4403" etc.
Also, ich möchte alle Dateien, die mit der Zahl vor dem Unterstrich anfangen, in den jeweils dazugehörigen Ordner verschieben. Falls dieser noch nicht existiert soll einer erstellt werden.
Ich hoffe ich habe mein Vorhaben verständnisvoll geschildert.
Vielen Dank schon mal im voraus !
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 177759
Url: https://administrator.de/forum/dateien-in-verschiedene-ordner-kopieren-177759.html
Ausgedruckt am: 22.04.2025 um 08:04 Uhr
14 Kommentare
Neuester Kommentar
Hallo weaslflink und willkommen im Forum!
Ohne Berücksichtigung bereits vorhandener Dateien im Zielordner würde sich das in einer Zeile abhandeln lassen (ungetestet zur Direkteingabe in CMD, daher nur mit %i und nicht, wie in einem Batch, mit %%i; das "
Grüße
bastla
[Edit] Fehlendes Anführungszeichen nach
Ohne Berücksichtigung bereits vorhandener Dateien im Zielordner würde sich das in einer Zeile abhandeln lassen (ungetestet zur Direkteingabe in CMD, daher nur mit %i und nicht, wie in einem Batch, mit %%i; das "
echo
" vor dem "xcopy
" sorgt für ein gefahrloses Testen, da so der Kopierbefehl nur angezeigt, aber nicht ausgeführt wird; Ziellaufwerk E: ):for /f "tokens=1* delims=_" %i in ('dir /b /a-d "%userprofile%\Eigene Dateien\myscans\*_*.pdf"') do @echo xcopy "%userprofile%\Eigene Dateien\myscans\%i_%j" "E:\%i\%i_%j*"
Falls die Datei schon vorhanden ist soll diese im namen eweitert werden, sodass ich beide Dateien behalte.
solltest Du noch etwas näher ausführen ...Grüße
bastla
[Edit] Fehlendes Anführungszeichen nach
pdf
ergänzt [/Edit]
Hallo weaslflink,
hier mein Vorschlag zur Lösung des Problems:
In den Zeilen 3-5 musst Du die Pfade ggf. anpassen. Dabei gilt zu beachten, dass keiner der beiden Pfade in Zeile 3 und 4 mit einem
Falls im Zielverzeichnis bereits Dateien vorhanden sind, die umbenannt werden müssen, geht das Script nach Art des Windows Explorers vor und hängt eine in Klammern stehende Zahl an den Dateinamen an (aus
Gruß
Friemler
[EDIT]
Ich habe die Anregung von bastla aufgegriffen, und das Nicht-Vorhanden-Sein des Zielverzeichnisses im Script berücksichtigt (wird durch die Verwendung von
[/EDIT]
[EDIT2]
Außerdem auch von mir noch eine Erklärung zur Funktionsweise des Unterprogramms
Dem Unterprogramm wird in Zeile 8 der Zielpfad+Name der aktuell betrachteten Quelldatei als Parameter übergeben. Im Unterprogramm kann er über
Mit
Die somit erzeugte Dateimaske wird dem
Die Ausgabe von
Der Doppelpunkt ist mit
Innrhalb der
In Zeile 22 wird geprüft, ob der Wert von
Der ursprüngliche Name steht in der Variablen
Mit
[/EDIT2]
hier mein Vorschlag zur Lösung des Problems:
@echo off & setlocal
set "SrcDir=%UserProfile%\Eigene Dateien\myscans"
set "DestDir=E:"
set "FileType=pdf"
for /f "tokens=1* delims=_" %%a in ('dir /b /a:-d "%SrcDir%\*_*.%FileType%" 2^>NUL') do (
call :RenOldVersion "%DestDir%\%%a\%%a_%%b"
xcopy "%SrcDir%\%%a_%%b" "%DestDir%\%%a\%%a_%%b*" > NUL
)
exit /b
:RenOldVersion
set /a "NumFiles=0"
for /f "tokens=1 delims=:" %%c in ('dir /b /a:-d "%~dpn1*%~x1" 2^>NUL ^| findstr /n "^"') do (
set /a "NumFiles=%%c"
)
if %NumFiles% gtr 0 ren "%~1" "%~n1(%NumFiles%)%~x1"
exit /b
In den Zeilen 3-5 musst Du die Pfade ggf. anpassen. Dabei gilt zu beachten, dass keiner der beiden Pfade in Zeile 3 und 4 mit einem
\
(Backslash) enden darf. Im Beispielcode oben würden die Zielverzeichnisse 3413, 20501, 4403
etc. im Wurzelverzeichnis von Laufwerk E:
gesucht.Falls im Zielverzeichnis bereits Dateien vorhanden sind, die umbenannt werden müssen, geht das Script nach Art des Windows Explorers vor und hängt eine in Klammern stehende Zahl an den Dateinamen an (aus
3413_13354789.pdf
wird z.B. 3413_13354789(1).pdf
oder 3413_13354789(2).pdf
). Die Zahl hängt von der Anzahl bereits existierender Versionen der Datei ab. Erledigt wird das ganze im Unterprogramm RenOldVersion
.Gruß
Friemler
[EDIT]
Ich habe die Anregung von bastla aufgegriffen, und das Nicht-Vorhanden-Sein des Zielverzeichnisses im Script berücksichtigt (wird durch die Verwendung von
XCOPY
bei Bedarf angelegt).[/EDIT]
[EDIT2]
Außerdem auch von mir noch eine Erklärung zur Funktionsweise des Unterprogramms
RenOldVersion
(das Hauptprogramm baut auf bastlas ursprünglichem Code auf und lässt sich deshalb mit Hilfe seiner ausführlichen Erklärung verstehen):Dem Unterprogramm wird in Zeile 8 der Zielpfad+Name der aktuell betrachteten Quelldatei als Parameter übergeben. Im Unterprogramm kann er über
%1
(der erste Parameter) angesprochen werden.Mit
%~dpn1
in Zeile 18 wird der Parameter in Laufwerk (d) + Pfad (p) + Dateiname (n) ohne Dateierweiterung zerlegt (aus E:\PDF-Dokumente\3413_13354789.pdf
wird E:\PDF-Dokumente\3413_13354789
). Dem wird ein *
angehängt (damit vom DIR
-Befehl auch schon existierende Dateien mit einer in Klammern eingeschlossenen Laufnummer gefunden werden). Daran wird mit %~x1
die Dateierweiterung (also .pdf
) angehängt.Die somit erzeugte Dateimaske wird dem
DIR
-Befehl übergeben, der wegen dem Parameter /a:-d
nur Dateien findet und wegen dem Parameter /b
nur eine Liste mit deren Namen ohne Pfad und ohne den üblichen Header und Footer der DIR
-Ausgabe erzeugt. Falls der Pfad nicht bzw. keine passende Datei existiert, würde DIR
eine Fehlermeldung ausgeben, was dazu führen würde, dass der Code innerhalb der FOR
-Schleife fälschlicherweise ausgeführt wird. Deshalb wird mit 2^>NUL
der Fehlerkanal zum NUL-Device umgeleitet, die Fehlermeldung wird somit verschluckt und der Schleifenrumpf nicht ausgeführt (das Zirkumflex-Zeichen ^
in 2^>NUL
ist nur an dieser Stelle, im Kopf der FOR
-Schleife, erforderlich, um das >
-Zeichen zu "escapen").Die Ausgabe von
DIR
wird wegen ^|
(auch hier dient das ^
zum "escapen" von |
) über eine Pipe an den Befehl FINDSTR
weitergeleitet, der wegen dem Parameter "^"
(ein sog. regulärer Ausdruck) Zeilen mit einem Anfang findet (also alle Zeilen) und wegen /n
Zeilennummern mit einem nachfolgenden Doppelpunkt vor jede Zeile schreibt.Der Doppelpunkt ist mit
delims=:
für die FOR
-Schleife als Trennzeichen innerhalb einer Zeile definiert. Wegen tokens=1
wird nur der Teil des Zeileninhalts an die Laufvariable %%c
zugewiesen, der vor dem Doppelpunkt steht, also die Zeilennummer, die von FINDSTR
erzeugt wurde.Innrhalb der
FOR
-Schleife wird diese Zeilenummer bei jedem Durchlauf an die Variable NumFiles
zugewiesen. Nach dem Abschluss der Schleife enthält NumFiles
also die Anzahl der Dateien, auf die das Suchmuster passt oder (wegen Zeile 16) den wert 0, wenn es keine solchen Dateien gibt.In Zeile 22 wird geprüft, ob der Wert von
NumFiles
größer 0 ist, wenn ja wird die gefundene Datei mit REN
umbenannt.Der ursprüngliche Name steht in der Variablen
%1
(die Tilde ~
in "%~1"
entfernt evtl. vorhandene Anführungszeichen, in die der Inhalt von %1
eingeschlossen sein könnte; außerdem wird damit der Inhalt von %1
auf jeden Fall mit Anführungszeichen eingeschlossen; hier nicht unbedingt notwendig, ist aber eine Angewohnheit von mir, solche Dinge zu coden), der neue Name wird mit %~n1(%NumFiles%)%~x1
erzeugt (%~n1
liefert den Dateinamen ohne Dateierweiterung, daran wird mit (%NumFiles%)
die in Klammern eingeschlossene Laufnummer und mit %~x1
die Dateierweiterung angehängt).Mit
exit /b
in Zeile 23 wird zum Hauptprogramm zurückgesprungen.[/EDIT2]
Hallo weaslflink!
Zur gewünschten Erklärung:
trennt die in weiterer Folge erzeugten Zeilen anhand des ersten "_", sodass in %i der Teil davor und in %j der Teil danach steht (sollten noch weitere "_" enthalten sein, bleiben diese erhalten, da wegen des "*" in "1*" keine weitere Zerlegung vorgenommen wird).
erzeugt wegen "/a-d" ein Inhaltsverzeichnis nur von Dateien, nicht auch von Ordnern, welch ev ebenfalls dem Suchmuster "*_*.pdf" entsprechen würden und gibt (wegen "/b") als einzige Information je Datei nur deren Namen + Typ aus (zur Zerlegung wie oben besprochen).
Da sich jetzt in %i und %j die benötigten Namensteile befinden, können diese für das Kopieren nach Wunsch zusammengesetzt werden - für die Datei "3413_13354789.pdf" wäre demnach %i=3413 und %j=13354789.pdf und daraus ergäbe sich der Befehl
Die Verwendung von "
welche nicht mit einem Schalter analog zu "/I" (womit festgelegt wird, dass das Ziel ein Verzeichnis sein soll) verhindert werden kann - daher der Trick mit dem angefügten "*" (der könnte nicht am Ende eines Verzeichnisnamens verwendet werden, daher muss das Ziel eine Datei sein).
Was das ev erforderliche Umbenennen angeht, hat Friemler ja schon einen Vorschlag unterbreitet (wobei ich allerdings eher die bereits vorhandenen Dateien unverändert lassen und der neu zu kopierenden Datei die Laufnummer hinzufügen würde) ...
Grüße
bastla
Habe es auch direkt ausprobiert (als als bat mit zwei %%) jedoch ohne Erfolg.
Wenn Du es nochmals (und jetzt auch mit dem inzwischen oben nachgetragenen fehlenden Anführungszeichen) versuchst, sollte es klappen ...Zur gewünschten Erklärung:
for /f "tokens=1* delims=_" %i in
('dir /b /a-d "%userprofile%\Eigene Dateien\myscans\*_*.pdf"')
do @echo xcopy "%userprofile%\Eigene Dateien\myscans\%i_%j" "E:\%i\%i_%j*"
@echo xcopy "%userprofile%\Eigene Dateien\myscans\3413_13354789.pdf" "E:\3413\3413_13354789.pdf*"
xcopy
" hat den Vorteil, dass bei Bedarf der Zielordner erstellt wird. Nachteilig wäre die NachfrageIst das Ziel E:\3413\3413_13354789.pdf ein Dateiname
oder ein Verzeichnisname
(D = Datei, V = Verzeichnis)?
Was das ev erforderliche Umbenennen angeht, hat Friemler ja schon einen Vorschlag unterbreitet (wobei ich allerdings eher die bereits vorhandenen Dateien unverändert lassen und der neu zu kopierenden Datei die Laufnummer hinzufügen würde) ...
Grüße
bastla
@Friemler
Dein Ansatz berücksichtig (noch) nicht, dass der Zielordner ev erst erstellt werden muss ...
Grüße
bastla
Dein Ansatz berücksichtig (noch) nicht, dass der Zielordner ev erst erstellt werden muss ...
Grüße
bastla
Hallo bastla,
da Du dafür schon einen schönen Trick präsentiert hast (danke, wieder was gelernt
), habe ich ihn kurzerhand in mein Script eingebaut.
Btr. "Umbenennen der alten Versionen": Meine Methode hat den Vorteil, dass die aktuelle Version der Datei zu jeder Zeit den gleichen Namen hat. Somit ist es einfacher, aus anderen Scripten/Programmen darauf Bezug zu nehmen. Was letztendlich besser ist, kommt auch auf die (vom TO nicht näher erläuterten) Anforderungen an.
Gruß
Friemler
Zitat von @bastla:
Dein Ansatz berücksichtig (noch) nicht, dass der Zielordner ev erst erstellt werden muss ...
Dein Ansatz berücksichtig (noch) nicht, dass der Zielordner ev erst erstellt werden muss ...
da Du dafür schon einen schönen Trick präsentiert hast (danke, wieder was gelernt
Btr. "Umbenennen der alten Versionen": Meine Methode hat den Vorteil, dass die aktuelle Version der Datei zu jeder Zeit den gleichen Namen hat. Somit ist es einfacher, aus anderen Scripten/Programmen darauf Bezug zu nehmen. Was letztendlich besser ist, kommt auch auf die (vom TO nicht näher erläuterten) Anforderungen an.
Gruß
Friemler
Hallo weaslflink!
Wenn ich
betrachte (was mir mit der passenden leichter fällt
), bin ich mir nicht so ganz sicher, dass der Quellpfad
lauten sollte ...
Grüße
bastla
Wenn ich
C:\Users\pzhqch\Documents\My Scans\test>set "SrcDir=C:\Users\pzhqch\Eigene Dateien\myscans\test"
C:\Users\pzhqch\Eigene Dateien\myscans\test
Grüße
bastla
Hallo weaslflink!
Wenn sicher gestellt ist, dass nur der Dateiname vor einer ev ersten Klammer benötigt wird, dann (weitgehend ungetestet) etwa so:
Eine Alternative zu den Zeilen 12 und 13 könnte übrigens so aussehen:
Grüße
bastla
Wenn sicher gestellt ist, dass nur der Dateiname vor einer ev ersten Klammer benötigt wird, dann (weitgehend ungetestet) etwa so:
@echo off & setlocal
set "SrcDir=%userprofile%\Documents\My Scans\test"
set "DestDir=%userprofile%\Documents\My Scans\test2"
set "FileType=pdf"
for /f "tokens=1* delims=_" %%a in ('dir /b /a-d "%SrcDir%\*_*.%FileType%" 2^>NUL') do (
for /f "delims=(" %%i in ("%%~nb") do call :Kopieren "%SrcDir%\%%a_%%b" "%%a" "%%i" "%%~xb"
)
exit /b
:Kopieren
set /a "NumFiles=0"
for /f "tokens=1 delims=:" %%c in ('dir /b /a-d "%DestDir%\%~2\%~2_%~3*%~4" 2^>NUL ^| findstr /n "^"') do set /a "NumFiles=%%c"
set /a NumFiles+=1
if %NumFiles% gtr 1 (
xcopy %1 "%DestDir%\%~2\%~2_%~3(%NumFiles%)%~4*"
) else (
xcopy %1 "%DestDir%\%~2\%~2_%~3%~4*"
)
exit /b
for /f %%c in ('dir /b /a-d "%DestDir%\%~2\%~2_%~3*%~4" 2^>NUL ^|find /c /v "?"') do set /a "NumFiles=%%c"
bastla
Moin weaslflink,
Wärest du bereit, diesen Dank für die weniger lesefähigen in diesem Forum zu visualisieren, vorzugsweise in diesem dezenten Wacholderton?
Brennesselfarben ginge zur Not auch....
Grüße
Biber
Wärest du bereit, diesen Dank für die weniger lesefähigen in diesem Forum zu visualisieren, vorzugsweise in diesem dezenten Wacholderton?
Brennesselfarben ginge zur Not auch....
Grüße
Biber