Unterordner in A-Z Ordnerstruktur einsortieren per (Windows) Batch Datei
Hallo,
Ich bin nicht wirklich fit was Batch Dateien angeht, und scheitere deshalb an einer Batchdatei die mir etwas Arbeit abnehmen soll:
Ich habe einen Ordner mit vielen verschiedenen Unterordern - nun möchte ich diese in eine bereits vorhandene 0-9 und A-Z Struktur einsortieren.
Die Batch-Datei soll also den ersten Buchstaben des Ordner-names erkennen und diesen dann mit allen darin vorhandenen Dateien in einen Ordner verschieben.
Z.B. sind folgende Ordner vorhanden:
Rügen-Urlaub, Rialto-Eisessen, Egenhausen-Turnier, Estland
diese sollen dann entweder in den Ordner E oder R verschoben werden,
falls in E z.B. schon ein Ordner Egenhausen vorhanden ist, soll der neu zu verschiebende Ordner in NeuEgenhausen oder etwas anderes umbenannt werden.
Klar könnte ich das auch so machen wie bisher: Im Explorer nach Alphabet sortieren und dann per Maus verschieben, aber da Wöchentlich mehrere neue Ordner dazu kommen wird mir das auf dauer relativ lästig...
einzelne Dateien mit bestimmten Anfangsbuchstaben zu verschieben bekomme ich hin, aber ich weiß leider nicht wie ich die Anfangsbuchstaben von Ordnern auslesen kann und diese Ordner verschieben kann
Vielen Dank schon im vorraus für eure Hilfe!!!
Content-ID: 97549
Url: https://administrator.de/contentid/97549
Ausgedruckt am: 23.11.2024 um 01:11 Uhr
Das könnte etwa so gehen:
@echo off & setlocal
set "Quelle=D:\Alle Meine Fotos"
set "Ziel=D:\Fotos alphabetisch"
for /d %%i in ("%Quelle%\*.*") do call :ProcessDir "%%i"
goto :eof
:ProcessDir
set "Verz=%~nx1"
echo Bearbeite: %Verz%
set "B=%Verz:~,1%"
if not exist "%Ziel%\%B%\" goto :eof
set /a Index=1
:Check
if not exist "%Ziel%\%B%\%Verz%" goto :MoveIt
set Index+=1
set "Verz=%~nx1-%Index%"
goto :Check
:MoveIt
move %1 "%Ziel%\%B%\%Verz%">nul
goto :eof
echo Verschiebe %~nx1 nach "%Ziel%\%B%\%Verz%"
Anders als von Dir vorgeschlagen, wird für den Fall, dass im Zielordner bereits ein gleichnamiger Ordner vorhanden ist, eine laufende Nummer angefügt - das Ergebnis wäre lt Deinem Beispiel dann: "Egenhausen-Turnier-2"; sollte es auch diesen Ordner schon geben, wird der Index solange erhöht, bis die nächste freie Nummer gefunden wird (zB "Egenhausen-Turnier-5").
Grüße
bastla
Nur als Anmerkung: die "xcopy"-Schalter "/s" ("/e" erledigt das mit) sowie (da im Zielordner nichts zu überschreiben ist - dieser wurde ja eben erst erstellt) "/r", "/d" und "/y" sind überflüssig, und mit
rd /s /q %1
Grüße
bastla
Dateien alphabetisch sortiert zu kopieren=verschieben per BATCH.
Die Befehle move und xcopx bewegen alle Dateien nur in der Reihenfolge, wie sie zufällig in der $MFT stehen (in der Reihenfolge ihrer Erstellung).
Ich möchte aber sicherstellen, daß diese trotzdem in alphanumerischer Reihenfolge bewegt werden! Denn dann werden sie auf einem anderen Datenträger in alphanummerischer Reihenfolge in die FAT=MFT geschrieben.
Doch genau darauf ging hier noch keiner ein.
Außerdem bewegt der Befehl move alle Dateien, auch aus Unterverzeichnissen in NUR EINE Zielebene!
Der Befehl xCopy bewegt ganze Verzeichnisstrukturen, aber eben unsortiert!
Per "dir /b /S "Quelle" >Dateienliste.txt" kann man eine Liste anlegen, die sich mit "sort Dateienliste.txt Dateiensortiert.txt" sortieren läßt und in einer BATCH als Quelle für "move" verwenden läßt.
Aber: man müßte für move eine Stringverarbeitung einbauen, die die Verzeichnisstruktur von QUELLE für ZIEL zusammenbastelt. So daß eine Befehlszeile dynamisch erzeugt wird, die etwa so aussähe:
move D:\Alle Meine Fotos\Urlaub1998\*.jpg H:\Fotos alphabetisch\Urlaub1998\
wobei %Pfad%*.jpg aus der alphabetisch sortierten Liste zeilenweise entnommen werden soll, und \Urlaub1998\ auch ganz anders heißen könnte/können sollte.
Zweck:
viele MP3-Player, DVD-Player, digitale Bilderrahmen, spielen die Dateien in der Reihenfolge des Kopierens und somit der FAT=MFT ab und nicht alphabetisch!
Ich habe neulich über tausend mühevoll zusammengestellte und sortierte, sortiert benannte Fotos auf eine SD-Karte kopiert. Doch die ganze Mühe war umsonst, weil der Player/Bilderrahmen die Dateien "wild durcheinander" anzeigt!
Für das Problem des Aufteilens der vollen Pfadnamen habe ich in diesem Tread Batch zum Dateien bewegen zwar einen Gedankenansatz gefunden, aber leider noch nicht ganz vollständig verstanden.
Aus einer Zeile wie z.B.:
for /f "tokens=1-2* delims=_." %%i in ('dir /b *_*') do move %%i_%%j.%%k "%Ziel%\%%jTag"
müßte ich etwa das machen?)
for /f "tokens=1-2* delims=\" %%i in ('dir /b /s *.*') do move %%i_%%j.%%k "%Ziel%\%subdir1\%subdir2<\%subdir3>"
wobei mir unklar ist was "tokens=1-2" bedeutet und meine Dateinamen keine Datumsangaben enthalten und auch nicht danach einsortiert werden sollen, sondern in die alte Verseichnisstruktur im neunen Ziel mit altem Dateinamen. Die Anzahl der Subdirs ist variabel je nach Quelle.
Mit delims=\ wird wohl das Trennzeichen festgelegt? Kann es richtiger sein delims=:\ zu verwenden um auch den Laufwerksbuchstaben zu entfernen?
Was mir noch nicht klar ist: Einerseits bemängelst Du
Für ein einfaches "Umlagern" in eine neue Struktur unter Berücksichtigung der alphabetischen Reihenfolge innerhalb jedes einzelnen Verzeichnisses könnte das, auf Basis Deines Beispieles, etwa so aussehen:
@echo off & setlocal
set "Typ=jpg"
set "Basis=D:\Alle Meine Fotos\Urlaub1998"
set "Ziel=H:\Fotos alphabetisch\ganz anders"
for /f "delims=" %%i in ('dir /s /b /on "%Basis%\*.%Typ%"') do call :ProcessFile "%%i"
pause
goto :eof
:ProcessFile
set "Pfad=%Ziel%%~dp1"
call set "Pfad=%%Pfad:%Basis%=%%"
echo md "%Pfad%" 2>nul
echo move %1 "%Pfad%"
goto :eof
echo
" am Beginn der Zeilen 13 und 14) nur eine Ausgabe der Befehle erzeugt, aber noch kein Zielverzeichnis erzeugt und keine Datei verschoben ...Grüße
bastla
Was mir noch nicht klar ist: Einerseits bemängelst Du
> Außerdem bewegt der Befehl move alle Dateien, auch aus Unterverzeichnissen in NUR EINE Zielebene!
Für mich dabei interessant der Zielaufbau.
für Quelle und Ziel darstellst, was Du genau erreichen willst?
set "Basis=D:\Alle Meine Fotos\Urlaub1998"
set "Ziel=H:\Fotos alphabetisch\ganz anders"
ist mir zu starr. Bei mir müßte es heißen:
set "Basis=D:\Alle Meine Fotos\Urlaub1998"
set "Ziel=H:\Alle Meine Fotos\Urlaub1998"
besser aber noch:
set Basis=%1
set Ziel=%2
denn meiner "moveetwas.bat" sollen auf der Kommandozeile die zwei Parameter Quelle und Ziel übergeben werden. und es soll sich nicht um bestimmte Dateitypen handeln.
Der Zielpfad soll also aus Teilen des Quellpfades generiert werden, nur ist Ziel meist ein anderer Laufwerksbuchstabe und eventuell darin ein anderer Erstordner, die sonstige Struktur der Ordner aber identisch an Parameter Ziel angehängt.
Also angenommen ich habe eine Quelle F:\Bilder\Celebrities\AngelinaJolie\
darin die Dateien
Angelina101.jpg
Angelina_Filmographie.txt
Angelina002.jpg
...
angelina174.jpg
und möchte diese auf eine SD-Karte aber alphabetisch sortiert kopiert haben für einen digitalen Bilderrahmen, der ja nur FAT hat. Das Quelllaufwerk ist eine FAT32-Partition. In deren MFT stehen die Dateien aber nicht in alphabetischer Reihenfolge, sondern in der Reihenfolge der Erstellung=ersten Speicherung. Auf dem digitalen Bilderrahmen, der Dateien in der Reihenfolge seiner FAT anzeigt, werden diese Bilder "wild durcheinander" angezeigt.
Ähnliches Problem ein MP3-Player mit SD-Karte. Die Titel stammen nicht von einem kontinuierlichen CD-Rip, sondern sind Ergebnis einer stückweisen Sammlung, so wie Angelinas Bilder auch. Der MP3-Player soll die Dateien aber alphanumerisch abspielen, und nicht "wild durcheinander"!
Für den digitalen bilderrahmen gilt das gleiche: er soll Bilder chronologisch=alphanumerisch abspielen und nicht "wild durcheinander, wie sie gerade vom WinExplorer kopiert wurden.
Ich las neulich NTFS würde die MFT alphanumerisch sortieren. Kann sein und wäre gut. FAT und FAT32 tun das nicht. daher der Wunsch nach einer BATCH-Datei, die das regelt. Wie ich das sortieren kann weis ich.
Ginge es nur um das reine kopieren/verschieben, bräuchte man keine BATCH-Datei, weil das auch der WinExplorer kann.
Für ein einfaches "Umlagern" in eine neue Struktur unter Berücksichtigung der alphabetischen Reihenfolge
innerhalb jedes einzelnen Verzeichnisses könnte das, auf Basis Deines Beispieles, etwa so aussehen:
@echo off & setlocal
> set "Typ=jpg"
> set "Basis=D:\Alle Meine Fotos\Urlaub1998"
> set "Ziel=H:\Fotos alphabetisch\ganz anders"
>
> for /f "delims=" %%i in ('dir /s /b /on "%Basis%\*.%Typ%"') do call :ProcessFile "%%i"
> pause
> goto :eof
>
> :ProcessFile
> set "Pfad=%Ziel%%~dp1"
> call set "Pfad=%%Pfad:%Basis%=%%"
> echo md "%Pfad%" 2>nul
> echo move %1 "%Pfad%"
> goto :eof
>
echo
" am Beginn der Zeilen 13 und 14) nur eine Ausgabe der Befehleerzeugt, aber noch kein Zielverzeichnis erzeugt und keine Datei verschoben ...
Ich las schon mehrere Batch-Tutorials, aber nie wurde die String-verarbeitung erklärt.
Ich arbeite seit einiger zeit mit WinXP, aber parallel noch mit anderen Betriebssystemen, die NTFS nicht können. Daher habe ich mehrere Partitionen mit FAT32 und in vielen Jahren gewachsenen Dateienbeständen. Ich arbeite seit fast 20 Jahren mit Computern. zuerst AmigaOS, später kamen Win3.1, Win95, Win98 bis hin zu XP dazu. Ansatzweise kenne ich Mac und Linux. Ich will hier aber keinen Betriebssystemstreit erzeugen.
Anderes Beispiel, gleiches Problem:
ich möchte die Bildersammlung von Poserbildern von der festplatte auf die SD-Karte kopieren. Pfade sollen teilweise übernommen werden. ich möchte meine BATCH damit aufrufen:
moveetwas.bat Q:\Metacreations\Poser\Bilder\fremde\*.* H:\Poser\Bilder\fremde
funktioniert solange ich nur in der Ebene \fremde\ bleibe.
Da das inzwischen weit über 500 sind und ich auch einen Ordner \eigene\ habe, dies aber nicht in der BATCH "fest verankern" will, soll die BATCH aus
moveetwas.bat Q:\Metacreations\Poser\Bilder\*.* H:\Poser\
die Zeilen generieren, die dann so aussehen könnten
move Q:\Metacreations\Poser\Bilder\fremde\11elf - Runen kh.jpg h:\Poser\Bilder\fremde\
move Q:\Metacreations\Poser\Bilder\fremde\11elf - Runen R.jpg h:\Poser\Bilder\fremde\
move Q:\Metacreations\Poser\Bilder\eigene\Victoria_01.jpg h:\Poser\Bilder\eigene\
usw.
Es muß also aus dem Quellpfad \Bilder\fremde\ und \Bilder\eigene\ ausgeschnitten werden und an %%Ziel angehängt. Oder eben andere Ordnernamen in anderen Fällen, daher variabel.
Grüße
Ronald
set "Ziel=H:\Fotos alphabetisch\ganz anders"
set "Ziel=H:\Alle Meine Fotos\Urlaub1998"
set "Basis=%~1"
set "Ziel=%~2"
die Zeilen generieren, die dann so aussehen könnten
move Q:\Metacreations\Poser\Bilder\fremde\11elf - Runen kh.jpg h:\Poser\Bilder\fremde\
move Q:\Metacreations\Poser\Bilder\fremde\11elf - Runen R.jpg h:\Poser\Bilder\fremde\
move Q:\Metacreations\Poser\Bilder\eigene\Victoria_01.jpg h:\Poser\Bilder\eigene\
moveetwas.bat Q:\Metacreations\Poser\Bilder\*.* H:\Poser\Bilder
Zur Zerlegung von Schleifenvariablen (wie etwa nur Verwendung von Laufwerk und Pfad = %%~dpi bzw %~dp1, wenn ein Parameter unterteilt werden soll) siehe "
for /f
" (ziemlich gegen Ende), die Erzeugung von Teilstrings und deren Ersetzung wird in der Hilfe zu "set
" beschrieben ...[Nachtrag]
Eine Variation des obigen Batches zum Kopieren (inkl versteckter / System-Dateien) mit der Möglichkeit, wie gewünscht auch die Dateiauswahl der Quelldaten per Aufrufparameter zu steuern, sähe etwa so aus:
@echo off & setlocal
set "Dateien=%~nx1"
set "Basis=%~dp1"
set "Ziel=%~2"
for /f "delims=" %%i in ('dir /s /b /on /a-d "%Basis%%Dateien%"') do call :ProcessFile "%%i"
goto :eof
:ProcessFile
set "Pfad=%Ziel%\%~dp1"
call set "Pfad=%%Pfad:%Basis%=%%"
xcopy /L /yhrkf %1 "%Pfad%*"|findstr /v /c:"1 Datei(en) kopiert"
goto :eof
xcopy
"-Schalters "/L" wird tatsächlich kopiert ...Der Aufruf muss in diesem Fall nach dem Muster
copyetwas.cmd Q:\Metacreations\Poser\Bilder\*.* H:\Poser\Bilder
copyetwas.cmd Q:\Metacreations\Poser\Bilder\201?-*.jpg H:\Poser\Bilder
Grüße
bastla
P.S.: Ob in diesem oder einem neuen Thread: Verwende bitte "<code>"- und "</code>"-Tags zum Posten von (Batch-)Code ...
danke für die Antwort.
Da die Klärung meiner Problemstellung doch ausschweifender wird, als ich zuerst dachte, würde ich einen Moderator bitten, wenn möglich meinen Teil dieses Treads in einen neuen zu verlagern und nur jeweils einen Linkverweis auf den anderen einzubauen, da es jetzt doch zu weit von dem Ursprungsproblem des Treaderöffners abweicht.
Titelvorschlag: "Wie Pfadbestandteile des Quellpfades in Zielpfad einer BATCH einbauen per Stringverarbeitung?"
und ja ich werde in zukunft "
"-und-"
Ich habe dein copyetwas.cmd ausprobiert, aber leider tut es immer noch nicht was ich erreichen will. Ich denke man muß bei
for /f "delims=" %%i in ....
Wenn ich in der Befehlszeile
F:\Bilder\AdamUndEva\.picasa.ini -> M:\Bilder\.picasa.ini
0 Datei(en) kopiert
F:\Bilder\AdamUndEva\16137_fastentuch-01_Adam+Eva.jpg -> M:\Bilder\16137_fastentuch-01_Adam+Eva.jpg
F:\Bilder\AdamUndEva\2816_Paar.jpg -> M:\Bilder\2816_Paar.jpg
F:\Bilder\AdamUndEva\Adam-and-Eve-Posters.jpg -> M:\Bilder\Adam-and-Eve-Posters.jpg
F:\Bilder\AdamUndEva\Adam-and-Eve-Posters2.jpg -> M:\Bilder\Adam-and-Eve-Posters2.jpg
F:\Bilder\AdamUndEva\Eve_tempted.jpg -> M:\Bilder\Eve_tempted.jpg
F:\Bilder\AdamUndEva\pano.jpg -> M:\Bilder\pano.jpg
F:\Bilder\AdamUndEva\pano.txt -> M:\Bilder\pano.txt
F:\Bilder\AdamUndEva\pspbrwse.jbf -> M:\Bilder\pspbrwse.jbf
Verwende ich dein copyetwas.cmd auf einen anderen Ordner mit Subordnern, passiert dann doch ungefähr das was ich will:
(Ausgabe in DOS-Box)
F:\Bilder\Alboin\4bc-Dateien\Born2.gif -> M:\Bilder\4bc-Dateien\Born2.gif
F:\Bilder\Alboin\4bc-Dateien\centBarREV.gif -> M:\Bilder\4bc-Dateien\centBarREV.gi
F:\Bilder\Alboin\4bc-Dateien\NavA.gif -> M:\Bilder\4bc-Dateien\NavA.gif
F:\Bilder\Alboin\4bc-Dateien\NavC.gif -> M:\Bilder\4bc-Dateien\NavC.gif
F:\Bilder\Alboin\4bc-Dateien\ScavengerSPECTRUMHead.jpeg -> M:\Bilder\4bc-Dateien\S
F:\Bilder\Alboin\4bc-Dateien\ScavNav.gif -> M:\Bilder\4bc-Dateien\ScavNav.gif
F:\Bilder\Alboin\4bc-Dateien\TSTitle.gif -> M:\Bilder\4bc-Dateien\TSTitle.gif
F:\Bilder\Alboin\3bc-Dateien\Blkbkg.gif -> M:\Bilder\3bc-Dateien\Blkbkg.gif
F:\Bilder\Alboin\3bc-Dateien\Born2.gif -> M:\Bilder\3bc-Dateien\Born2.gif
F:\Bilder\Alboin\3bc-Dateien\centBarREV.gif -> M:\Bilder\3bc-Dateien\centBarREV.gi
F:\Bilder\Alboin\3bc-Dateien\NavA.gif -> M:\Bilder\3bc-Dateien\NavA.gif
F:\Bilder\Alboin\3bc-Dateien\NavC.gif -> M:\Bilder\3bc-Dateien\NavC.gif
F:\Bilder\Alboin\3bc-Dateien\ScavengerSPECTRUMHead.jpeg -> M:\Bilder\3bc-Dateien\S
F:\Bilder\Alboin\3bc-Dateien\ScavNav.gif -> M:\Bilder\3bc-Dateien\ScavNav.gif
F:\Bilder\Alboin\3bc-Dateien\TSTitle.gif -> M:\Bilder\3bc-Dateien\TSTitle.gif
F:\Bilder\Alboin\2bc-Dateien\Blkbkg.gif -> M:\Bilder\2bc-Dateien\Blkbkg.gif
F:\Bilder\Alboin\2bc-Dateien\Born2.gif -> M:\Bilder\2bc-Dateien\Born2.gif
F:\Bilder\Alboin\2bc-Dateien\centBarREV.gif -> M:\Bilder\2bc-Dateien\centBarREV.gi
F:\Bilder\Alboin\2bc-Dateien\NavA.gif -> M:\Bilder\2bc-Dateien\NavA.gif
F:\Bilder\Alboin\2bc-Dateien\NavC.gif -> M:\Bilder\2bc-Dateien\NavC.gif
F:\Bilder\Alboin\2bc-Dateien\ScavengerSPECTRUMHead.jpeg -> M:\Bilder\2bc-Dateien\S
F:\Bilder\Alboin\2bc-Dateien\ScavNav.gif -> M:\Bilder\2bc-Dateien\ScavNav.gif
F:\Bilder\Alboin\2bc-Dateien\TSTitle.gif -> M:\Bilder\2bc-Dateien\TSTitle.gif
F:\Bilder\Alboin\1bc-Dateien\Blkbkg.gif -> M:\Bilder\1bc-Dateien\Blkbkg.gif
F:\Bilder\Alboin\1bc-Dateien\Born2.gif -> M:\Bilder\1bc-Dateien\Born2.gif
F:\Bilder\Alboin\1bc-Dateien\CaesarBtn.gif -> M:\Bilder\1bc-Dateien\CaesarBtn.gif
F:\Bilder\Alboin\1bc-Dateien\centBarREV.gif -> M:\Bilder\1bc-Dateien\centBarREV.gi
F:\Bilder\Alboin\1bc-Dateien\NavA.gif -> M:\Bilder\1bc-Dateien\NavA.gif
F:\Bilder\Alboin\1bc-Dateien\NavC.gif -> M:\Bilder\1bc-Dateien\NavC.gif
F:\Bilder\Alboin\1bc-Dateien\ScavengerSPECTRUMHead.jpeg -> M:\Bilder\1bc-Dateien\S
F:\Bilder\Alboin\1bc-Dateien\ScavNav.gif -> M:\Bilder\1bc-Dateien\ScavNav.gif
F:\Bilder\Alboin\1bc-Dateien\TSTitle.gif -> M:\Bilder\1bc-Dateien\TSTitle.gif
Das bedeutet ich hätte
Denn nun wird \Alboin\ im Zielpfad eingebaut!
Damit sind wir auf dem Weg den ich suchte.
Funktioniert das aber statt mit xcopy auch mit move?
Und hier mal noch der code, den ich zuerst geschrieben hatte, der nur mit einer Ebene funktioniert, und den ich umbauen wollte:
move2.bat
@ECHO OFF
:anfang
IF "%1"=="/?" GOTO help
IF "%1"=="" GOTO fehler
IF "%2"=="" GOTO fehler2
echo Die aktuelle Datei heißt %0%.
REM Dieser Befehl erzeugt eine Pfad:Datei-Liste ohne Zusatzinfos und aber sortiert, jedoch mit vollem Pfad.
dir /N /b /O:N /X %1 > Dateiliste.txt
REM den Parameter /S von DIR mußte ich wieder entfernen, weil alles nur in eine flache Zielstruktur kopiert wird.
set TEXT_T="Dateiliste.txt"
for /f "eol= tokens=* delims= usebackq" %%i in (%TEXT_T%) do (
echo move "%%i" %2 >>movelist.bat
)
REM die folgende zeile kann auskommentiert werden
call notepad Dateiliste.txt
call notepad movelist.bat
GOTO ende
REM (ewentuell weitere Befehle)
:help
echo move2.bat $VER:0.4 17.05.2010
echo Nutzen: Dateien und Ordner in sortierter Form verschieben.
echo.
echo SYNTAX: move2.bat [Quelle:] [Ziel:]
echo.
GOTO ende
:fehler
echo "1. Parameter fehlt!"
:fehler2
echo "2. Parameter fehlt!"
:ende
rem del Dateiliste.txt
echo fertig.
REM --- :EOF
Grüße Ronald
Um aus dem "
copy
" ein "move
" zu machen, müsste nur nach erfolgreicher Kopie die Originaldatei gelöscht werden - die Zeile 12 würde dann (wieder zur Sicherheit mit "echo
") so aussehen:xcopy /L /yhrkf %1 "%Pfad%*"|findstr /v /c:"1 Datei(en) kopiert" && echo del /f /a %1
bastla
natürlich hätte ich deine Erklärungen gern "ernst genommen", wenn ich sie gleich verstanden hätte! ;)
Aber egal, ich danke dir trotzdem für deine Hilfe.
Da ich solche Scripte nicht täglich anwende und mich auch nicht täglich damit befasse, (Vergessen von Details kann auftreten), bevorzuge ich eine Programierung die Fehler abfängt und anzeigt bzw. Hilfen gibt; so wie im Beispiel "move2.bat".
Dieses "del /f /a %1" hätte ich nun gern noch als Auswahlabrfage.
So in der Art:
echo "willst du die Quelldateien löschen, gib "y" ein, sonst "n"
if Eingabe="y" do (del /f /a %1)
else if Eingabe="n" do (go to :EOF) ; (oder einer anderen Sprungmarke)
if Eingabe="" do ("Frage wiederholen")
REM und abfragen des letzten Zeichens der Quellangabe
if lastchar %%Quelle="\" then do call Syntaxhinweis
:Syntaxhinweis
echo "wenn das letzte Zeichen von Quelle ein "\" ist, geht dieser Ordner verloren. Quellpfad bitte ohne "\" eingeben.
goto :Start (oder :EOF)
Unklar ist mir leider immernoch, was so einzelne Platzhalter bedeuten:
Was ist %~nx1?
was ist %-dpi?
Was ist %-dp1?
Was ist %-1?
Was ist %-2?
Was ist %-%%?
Was ist %i?
Was ist %j?
Was ist %k?
Was ist set "B=%Verz:~,1%" ?
Grüße Ronald
Du hast in der Liste noch vergessen:
Was ist "for /?"?
Was ist "set /?"?
echo "wenn das letzte Zeichen von Quelle ein "\" ist, geht dieser Ordner verloren. Quellpfad bitte ohne "\" eingeben.
... denn eigentlich steht doch oben (samt Beispiel, aber zugegebener Maße noch nicht in "fett"):
Die Abfrage hinsichtlich des Löschens
@echo off & setlocal
set "Dateien=%~nx1"
set "Basis=%~dp1"
set "Ziel=%~2"
set "Verschieben="
:Loop
set "Eingabe="
set /p Eingabe=Willst du die Quelldateien loeschen, gib "y" ein:
if not defined Eingabe goto :Loop
if /i "%Eingabe:~,1%"=="y" set "Verschieben=True"
echo\
if defined Verschieben (
echo Die Quelldaten werden verschoben = geloescht!
) else (
echo Die Quelldaten werden kopiert, nicht verschoben!
)
echo\
pause
for /f "delims=" %%i in ('dir /s /b /on /a-d "%Basis%%Dateien%"') do call :ProcessFile "%%i"
goto :eof
:ProcessFile
set "Pfad=%Ziel%\%~dp1"
call set "Pfad=%%Pfad:%Basis%=%%"
xcopy /L /yhrkf %1 "%Pfad%*"|findstr /v /c:"1 Datei(en) kopiert" && if defined Verschieben echo del /f /a %1
goto :eof
goto :eof
else
"-Zweig der Abfrage realisiert werden ...Grüße
bastla
ja ich hatte anfangs ein Pfadbeispiel mit \*.* geschrieben, aber auch, daß ich das flexibel haben will. Du klammerst dich zu sehr an EIN Pfadbeispiel.
Und ich wollte wissen, wie man den Quell-Pfad in Bestandteile zerlegt.
Du hast zwar ein Skript geschrieben, das auch in etwa mein Ziel erreicht, doch war es dabei plötzlich wichtig ob ein Quell-Ordner mit oder ohne "\" am Ende übergeben wird.
Übergebe ich deinen Skript eine Quelle mit "\*.*" am Ende passiert das Gleiche wie nur mit "\": der Ordner VOR den "\" geht verloren! Und das will ich nicht.
Dein Skript löst zwar die Aufgabe, aber ganz anders, als ich erfragte!
Meine Frage war:
Nach meiner Frage sollte die Zeile, die du mit xcopy machts, etwa so werden:
move %1 "%Ziel%\%Verz1%\%Verz2%"
oder je nach Pfadlänge auch
move %1 "%Ziel%\%Verz1%\%Verz2%\%Verz3%\%Verz4%"
In meinem ersten Post habe ich genau danach gefragt.
Wie bekomme ich die Zeile
for /f "tokens=1-2* delims=\" %%i in ('dir /b /s /O:N *.*') do move %%i_%%j.%%k "%Ziel%\%subdir1\%subdir2<\%subdir3>"
Und daher frage ich was %%j %%k usw bedeuten!
So wie du aber zuletzt geschrieben hast, bist leider du es der nicht versteht was ich will.
Und was ist falsch daran Syntaxhinweise und Fehlerabfragen in ein Script einzubauen?
Grüße Ronald
for /?
set /?
Grüße
bastla
ich bedauere sehr, wenn das hier zu einem unerwünschtem Mißverständnis führen würde!
Und ich finde es auch schade, wenn wir aneinander vorbeireden!
Denn ich bin für jede zielführende Hilfe sehr dankbar.
Es kann zwar sein, daß der Tread auf nicht sehr viele Leser hinausläuft, ich denke aber das das davon abhängt wie zielführend die Antworten ausfallen.
Denn in vielen anderen Foren wurde diese Problemstellung von anderen Fragern ebenfalls von den Antwortern nicht richtig verstanden und beantwortet!
Teilweise führte dies zu unsinnigen Betriebssystem-Streitereien oder unnützen Defragmentierungs-Ansichts-Diskusionen.
Unsinnig, weil: die Frage lautete: Wie löse ich das mit MS-DOS, und nicht womit (mit welchem Betriebssystem) löse ich das besser!
echo "wenn das letzte Zeichen von Quelle ein "\" ist, geht dieser Ordner verloren. Quellpfad bitte ohne "\" eingeben.
Dies ergab sich aber für mich erst durch deine Verwendung von xcopy und der anderen Vorgehensweise, als ich dachte! Das Ausprobieren DEINES Skriptes brachte mich zu dem Hinweis!
Auch wenn die Verwendung eines "\" am Ende des Quellpfades ein Fehler von mir war.
Es ist also eine Erkenntnis, die sich aus der Anwendung DEINES Skriptes ergab. Und die ich vorher SO nicht hatte!
Ich habe also aus der Anwendung DEINES Skriptes gelernt, welchen "Denkfehler" ICH hatte!
Ich wollte nicht VORHER am Zielpfad einen Subordner der Quelle einfügen müssen, sondern ihn per Stringbearbeitung aus dem Quellpfad generiert haben! Du mußt dich nicht wiederholen, sondern meine Problemstellung verstehen.
Dein ergänzter Vorschlag der Abfrage des Löschens gefällt mir aber schon ohne ihn ausprobiert zu haben!
Unklar und unbeantwortet bleibt leider weiterhin die Bedeutung von %%-dpi usw.
Freundliche Grüße
Ronald
echo "wenn das letzte Zeichen von Quelle ein "\" ist, geht dieser Ordner verloren. Quellpfad bitte ohne "\" eingeben.
Grüße
bastla
und ich dachte immer, neben den zwei Dingen, die Albert Einstein als Kandidaten für das Attribut "unendlich" bereits gefunden hat, wäre auch deine schier unerschöpfliche Geduld ein mögliches vollwertiges Drittes.
Ich kann eure Bedenken zerstreuen, dass dieser Thread nur von wenigen oder nur beiläufig gelesen wird.
Ich jedenfalls lese von Beginn an mit täglich wachsender Begeisterung mit.
@Roschka
Für dich noch mal zum Vorgehen unter Erwachsenen im Allgemeinen und in diesem Forum im Besonderen.
Zu den Eigenheiten unser aller Beschäftigung mit Computergelumpe gehört zwangsläufig, dass hier niemand alles wissen kann - dazu ist die Materie zu komplex oder vielleicht auch einfach zu umfangreich.
Das ist allerdings kein ITler-spezifisches Problem, sondern trifft genauso die Geigenbauer, Mezzosopranistinnen, Opel-Manta-Mechatroniker oder Sammler von Überraschungseiern.
Alle Einsteiger, alle Halb- und Vollprofis kommen irgendwann an eine Stelle, wo aus dem tiefsten Innersten herausbricht
"Upps, wassollndassein? Hab ich ja noch nie nich' gesehn...".
Und die dann weiterführende Informationen suchen, die zur Erhellung dieser Unklarheiten führen.
(--> "suchen" ist hier ein Tu-Wort, etwas aktiv zu leistendes. Von dir zu leistendes. Sonst hätte ich geschrieben ".... die auf Weihnachten warten")
bastla hat dich mehrfach und wiederholt (so wie ich mich jetzt mit dieser Tautologie wiederhole) auf die ultimativen Informationquellen wie z.B. FOR/? und SET/? verwiesen.
Ein ebenso mehrfaches und wiederholtes völliges Ausblenden dieser Hinweise war die Reaktion.
Bitte setz noch mal auf so vor vier oder fünf Kommentaren... und lies noch mal, was bastla dort empfohlen hat.
Danach, wenn das getan ist..
- oder -
stelle etwaige verbleibende Verständnisfragen
-oder-
nimm irgendwo Privatstunden
-oder-
Du wirst jedenfalls im Forum niemand finden, der sich mehr Geduld und Erklärungskompetenz als bastla zutraut und hier den Thread neu aufrollt.
Grüße
Biber
[Edit] Im Nachhinein musste ich zwei mögliche Optionen wieder streichen - Kollege Roschka ist gar nicht der Threadersteller.[/Edit]
was ich hier keinesfalls wollte, ist mit jemandem Streit anfangen!!!
Daß aber das Einbauen einer echo-Notitz und Fehlerabfragen in ein Skript, die gegen meine eigene Vergesslichkeit (wenn ich das skript mal länger nicht genutzt habe) helfen sollte, zu einem Streit führen könnte, hätte ich nicht geahnt. Dann hätte ich das nur heimlich zuhause reingeschrieben...
Ich habe eine Problemstellung und bin dankbar für hilfreiche Antworten. Das Skript von bastla funktioniert auch gut für den Zweck, aber eben komplett anders, als ich erfragte, und ich verstand leider nicht alles.
Dennoch ein freundliches Danke an bastla. Ich halte ihn für eine technischen Experten, der auch was kann.
Leider will er aber scheinbar nicht den Sinn der Variablen, nach denen ich fragte erklären. Schade.
Da dies auch kein anderer versuchte, möchte ich hier gern in einem freundlichen Ton zum Ende kommen.
Also vielen Dank für den Lösungsvorschlag.
Die Antwort auf die Frage nach der Bedeutung der Variablen fand ich nun hier:
http://www.windowsitpro.com/article/server-management/how-do-i-pass-par ...
Mit freundlichen Grüßen
Roschka
viele nennen mich "Biber, den Geduldigen".
Warum auch immer.
Einklagbar ist es jedenfalls nicht.
Ich versuch es noch mal zu erklären.
In der Hilfe zu For, die sich z.B. vom CMD-Prompt aus aufrufen lässt mit FOR /? steht
....
Zusätzlich wurde die Ersetzung von Verweisen auf FOR-Variablen erweitert.
Sie können jetzt folgende Syntax verwenden:
%~I - Expandiert %I und entfernt alle umschließenden
Anführungszeichen (").
%~fI - Expandiert %I zu einem vollständigen Dateinamen.
%~dI - Erzeugt nur den Laufwerkbuchstaben von %I.
%~pI - Erzeugt nur den Pfad von %I.
%~nI - Erzeugt nur den Dateinamen von %I.
%~xI - Erzeugt nur die Dateierweiterung von %I.
%~sI - Erzeugter Pfad enthält nur kurze Dateinamen.
%~aI - Erzeugt die Dateiattribute von %I.
%~tI - Erzeugt Datum und Zeit von %I.
%~zI - Erzeugt die Dateigröße von %I.
%~$PATH:I - Durchsucht die in der PATH-Umgebungsvariablen
angegebenen Verzeichnisse und expandiert die erste
gefundene Datei %I zu dem vollständigen Dateinamen.
Wenn der Name der Umgebungsvariablen nicht definiert
ist oder diese Datei bei der Suche nicht gefunden wurde,
wird dieser Parameter zu einer leeren Zeichenkette
expandiert.
Diese Parameter können auch miteinander kombiniert werden:
%~dpI - Erzeugt den Laufwerkbuchstaben und Pfad von %I.
%~nxI - Erzeugt den Dateinamen und die Dateierweiterung von %I.
%~fsI - Expandiert %I zu einem vollständigen Namen, der nur
kurze Dateinamen enthält.
%~dp$PATH:I - Durchsucht die in der PATH-Umgebungsvariablen
angegebenen Verzeichnisse nach %I und erzeugt den
Laufwerkbuchstaben und Pfad der ersten gefundenen Datei.
%~ftzaI - Expandiert %I zu einer Zeile, die der Ausgabe des DIR-
Befehls entspricht.
...
Darauf hatte bastla mehrfach verwiesen.
Zugegeben, im ersten Moment liest sich der Hilfetext möglicherweise etwas holprig.
in der Hilfe zu CMD/? oder CALL/? steht
...
Zusätzlich hat sich die Auflösung von Referenzen auf Argumente in Batchdateien
(%0, %1 etc.) wie folgt geändert:
%* in einer Batchdatei bezieht sich auf alle Argumente (z.B. %1 %2
%3 %4 %5 ...).
Die Ersetzung von Batchparametern (%n) wurde erweitert. Sie können
jetzt folgende Syntax benutzen:
%~1 - Expandiert %1 und entfernt umschließende
Anführungszeichen (").
%~f1 - Expandiert %1 zu einem vollständigen Dateinamen.
%~d1 - Erzeugt nur den Laufwerkbuchstaben von %1.
%~p1 - Erzeugt nur den Pfad von %1.
%~n1 - Erzeugt nur den Dateinamen von %1.
%~x1 - Erzeugt nur die Dateierweiterung von %1.
%~s1 - Der erzeugte Pfad enthält nur kurze Namen.
%~a1 - Expandiert %1 zu Dateiattributen.
%~t1 - Expandiert %1 zu Datum/Zeit der Datei.
%~z1 - Expandiert %1 zur Größe der Datei.
%~$PATH:1 - Durchsucht die in der PATH-Umgebungsvariablen
angegebenen Verzeichnisse und expandiert die erste
gefundene Datei %1 zu dem vollständigen Dateinamen.
Wenn der Name der Umgebungsvariablen nicht definiert
ist oder diese Datei bei der Suche nicht gefunden
wurde, wird dieser Parameter zu einer leeren
Zeichenkette expandiert.
Diese Parameter können auch miteinander kombiniert werden:
%~dp1 - Erzeugt den Laufwerkbuchstaben und Pfad von %1.
%~nx1 - Erzeugt den Dateinamen und die Dateierweiterung von %1.
...
Dann biegst du um Ecke und schreibst
Leider will er aber scheinbar nicht den Sinn der Variablen, nach denen ich fragte erklären. Schade.
Da dies auch kein anderer versuchte, möchte ich hier gern in einem freundlichen Ton zum Ende kommen.
Also vielen Dank für den Lösungsvorschlag.
Die Antwort auf die Frage nach der Bedeutung der Variablen fand ich nun hier:
http://www.windowsitpro.com/article/serve ...
..wo nun steht:
.....
Parameter Description
%1 The normal parameter.
%~f1 Expands %1 to a fully qualified pathname. If you passed only a filename from the current directory, this parameter would also expand to the drive or directory.
%~d1 Extracts the drive letter from %1.
%~p1 Extracts the path from %1.
%~n1 Extracts the filename from %1, without the extension.
%~x1 Extracts the file extension from %1.
%~s1 Changes the n and x options’ meanings to reference the short name. You would therefore use %~sn1 for the short filename and %~sx1 for the short extension.
The following table shows how you can combine some of the parameters.
Parameter Description
%~dp1 Expands %1 to a drive letter and path only.
%~sp1 For short path.
%~nx1 Expands %1 to a filename and extension only.
...
Okay..... sagen wir so...
Wenn das Thema für dich nun geklärt ist, sollten wir den Beitrag nicht mehr unnötig in die Länge ziehen.
Sonst bekomm ich bald einen neuen Beinamen.
Grüße
Biber
Danke an Biber für die Erklärung der %~-Variablen. Ich hatte leider übersehen, oder nicht richtig verstanden, daß ich in der Befehlszeile FOR /? usw. eingeben sollte, um diese Infos zu lesen.
Der Scriptvorschlag von bastla, vom 18.6.2010 an mich funktioniert einigermaßen gut, so lange man es auf kleine Ordnerstrukturen und ohne Leerzeichen in Quelle und Ziel zu haben anwendet, aber mit einem "Schönheitsfehler", für den bastla nichts kann: der DIR Befehl sortiert nur Dateien eines Verzeichnisses alphabetisch, nicht aber die Verzeichnisstrukturen selber.
Gemeint ist die Zeile:
for /f "delims=" %%i in ('dir /s /b /o:n %Basis%') do call :ProcessFile "%%i"
E:\>call :ProcessFile "e:\Dokumente und Einstellungen\All Users\Anwendungsdaten\
Adobe\Photoshop Elements\8.0\Photo Creations\frames\Gold Frame Round 2.metadata.
xml"
E:\>set "Pfad="O:\Programme_D\Dokumente und Einstellungen"e:\Dokumente und Einst
ellungen\All Users\Anwendungsdaten\Adobe\Photoshop Elements\8.0\Photo Creations\
frames\"
E:\>call set "Pfad=%Pfad:"e:\Dokumente und Einstellungen"=%"
E:\>md ""O:\Programme_D\Dokumente und Einstellungen"e:\Dokumente und Einstellungen\All Users\Anwendungsdaten\Adobe\Photoshop Elements\8.0\Photo Creations\frames\"
Ein Unterverzeichnis oder eine Datei mit dem Namen "O:\Programme_D\Dokumente" existiert bereits.
Folgender Fehler trat auf: O:\Programme_D\Dokumente.
Ein Unterverzeichnis oder eine Datei mit dem Namen "und" existiert bereits.
Folgender Fehler trat auf: und.
**Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.**
^CFolgender Fehler trat auf: Einstellungene:\Dokumente und Einstellungen\All Users\Anwendungsdaten\Adobe\Photoshop Elements\8.0\Photo Creations\frames\.
Batchvorgang abbrechen (J/N)? j
E:\>
umlagern.bat "D:\Dokumente und Einstellungen" "O:\Archive_D\Dokumente und Einstellungen".
Weil da Leerzeichen drin sind, muß man die Pfade in Anführungszeichen setzen.
(Jetzt aber bitte nicht diese Pfade monieren! Das sind Beispiele.)
Mein Konzept mit BATCH war von Anfang an folgendes:
1. starte das BATCH mit 2 Parametern QUELLE und ZIEL2. erzeuge eine Dateiliste mit dir (Quelle) /B /S /O':N >Dateiliste1.txt
3. sortiere diese mit: sort Dateiliste1.txt /O Dateiliste2.txt
4. lies diese Dateiliste2.txt im BATCH ein und wandle die Zeilen in move-Befehle um, so daß aus einer Zeile wie
X:\Hauptordner\Unterordner 1\ Unterordner2\Datei 1 mit Leerzeichen.ext
eine Zeile in der Art erstellt wird:
move "X:\Hauptordner\Unterordner 1\ Unterordner2\Datei 1 mit Leerzeichen.ext" "Y:\Archiv Ordner\Hauptordner\Unterordner 1\ Unterordner2"
in eine neue Datei umgeleitet.
5. diese movelist.bat soll mit "call notepad movelist.bat" vorübergehend zur Kontrolle angezeigt werden ob alles richtig umgesetzt wurde. wenn ja soll sie
6. ausgeführt werden. (Oder man kann in Notepad mit suchen & Ersetzen noch etwas korrigieren, und dann ausführen lassen)
7. Die Arbeitsdateien Dateiliste*.txt und movelist.bat sollen nach erfolgreicher Abarbeitung gelöscht werden.
Mein Problem bestand im Punkt 4. wie ich in der for-Schleife die Zeile aus der Dateiliste in Pfadbestandteile zerlegen kann um sie im Zielpfad wieder einzusetzen. Das Ziel wird IMMER ein anderer Laufwerksbuchstabe sein, kann auch, aber muß nicht, ein Hauptordner darin sein.
Das will ich flexibel nach Bedarf handhaben.
Ich fragte wie ich die FOR-Schleife zu diesem Zweck schreiben muß und wollte deshalb die %Parameter wissen. Statt dessen bekam ich Vorschläge, wie man sowas ähnliches ganz anders machen kann.
Die "fast" richtige Lösung sieht nun so aus:
...
REM ist nur ein Schnipsel ...
set TEXT_T="Dateiliste2.txt"
for /f "eol= tokens=* delims= usebackq" %%i in (%TEXT_T%) do (
set str=%Ziel%%%~pi
set str=!str:~0,-1!
echo if not exists "%Ziel%%%~pi/nul" md "!str!" >>movelistDoks.bat
echo move "%%i" "%Ziel%%%~pi" >>movelistDoks.bat
...
Der Backslash "\" wird nicht abgeschnitten!
Dabei habe ich doch oben in der Batch stehen setlocal ENABLEDELAYEDEXPANSION.
md x:\test\test2\ funktioniert aber auch ohne Fehlermeldung.
Ansonsten war das die Lösung nach der ich suchte.
Bei dem Anhängsel /nul bin ich nicht sicher ob es nicht \nul heißen müßte. Es soll ja sicherstellen, daß es sich um einen Ordner handelt und nicht um eine Datei.
Allerdings: egal wie das "nul" eingesetzt wird, kommt immer eine Fehlermeldung:
""D:\Programme\DjVuZone\DjVuLibre\share\djvu\djview4\/nul"" ist syntaktisch an dieser Stelle nicht verarbeitbar.
Ein anderes Problem entsteht jedoch im Falle umgekehrter Pfade, wenn ich aus y:\Archiv Ordner\ wieder nach X: schreiben will, möchte ich gerne den teil :\Archiv Ordner\ ausschneiden, weil der nicht im Ziellaufwerk erscheinen soll!
Ich will dann, daß aus Y:\Archiv Ordner\Hauptordner\usw. wieder als Ziel X:\Hauptordner\usw. wird.
Wie kann man das anders lösen, als mit notepad Suchen und Ersetzen?
Nur der Ordnung halber: Wenn Du Ausgaben eines Batches postest, dann bitte auch den Batch selbst dazu - und sei es nur, um erkennen zu können, dass er nicht meinem Ansatz vom 18.6.2010 entspricht: Dort wird nämlich ein Pfad mit enthaltenen Leerzeichen genau dann unter Anführungszeichen gesetzt, wenn diese auch tatsächlich benötigt werden; es kann nicht zu
E:\>set "Pfad="O:\Programme_D\Dokumente und Einstellungen"e:\Dokumente und Einstellungen\All Users\Anwendungsdaten\Adobe\Photoshop Elements\8.0\Photo Creations\frames\"
set "Ziel=D:\Fotos alphabetisch"
set "Ziel=O:\Programme_D\Dokumente und Einstellungen"
set Ziel="O:\Programme_D\Dokumente und Einstellungen"
Grüße
bastla
P.S.: Die besten Wünsche für die Umsetzung Deines Konzepts ...
du hast solange Recht, solange die Pfade so wie du es vorschlägst in die Batch-datei geschrieben werden.
Ich sagte aber schon immer, daß ich die Pfade als Parameter in der Befehlszeile an die Batch übergeben will!
und da sehen die beiden Set-Zeilen eben so aus:
@echo off & setlocal
...
set "Quelle=%1"
set "Ziel=%1"
...
Und dabei traten die Verstümmelungen auf. egal in welchem Script. Nimm das also bitte nicht persönlich.
Du hättest aber auch gleich schreiben können, daß du wegen DEM Problem mit den Anführungszeichen direkt in die Batch die Pfade schreibst und nicht als Parameter übergeben willst.
Gibt es denn eine Möglichkeit diese Anführungszeichen aus der Befehlszeile zu erkennen und zu entfernen bevor der String bearbeitet wird? Das wäre hilfreich.
Es treten aber auch noch andere Probleme auf, für die wir beide nichts können:
bescheuerterweise gibt es Dateien und Ordner mir Ausrufezeichen und Prozentzeichen im Namen die bei der Stringverarbeitung stören.
! Mein Ordner soll oben stehen
!! or nö meiner soll noch weiter oben sein
!!! Ätsch und meiner ist jetzt ganz obenj!
Sofort lesen!!!.txt
ein%20Bild.jpg
(oder noch blöder)
img@!325 (Dateinamen einer alten Webcam)
set str=%Ziel%%%~pi
set str=!str:~0,-1!
Und da kann weder bastla noch ich was dafür.
Das mit dem "/nul" habe ich aus "Windows 2003 Shell Scripting" abgeschrieben (gefunden bei Google books). es funktioniert aber nicht. Und set str=!str:~0,-1! leider scheinbar auch nicht, der Backslash bleibt dran am Pfad.
Schließlich genügt doch
set "Quelle=%~1"
bastla
>Das System kann die datei leider nicht finden
zurück.
Das System kann die angegebene Datei nicht finden.
bastla
P.S.: Irgendwie schade, dass das Ganze nicht auf meine Art durchgeführt werden darf:
@echo off & setlocal
set "Typ=jpg"
set "Basis=%~1"
set "Ziel=%~2"
for /f "delims=" %%i in ('dir /s /b /on "%Basis%\*.%Typ%"') do set "Pfad=%Ziel%%%~dpi" & set "Datei=%%i" & call :ProcessFile
pause
goto :eof
:ProcessFile
call set "Pfad=%%Pfad:%Basis%=%%"
echo md "%Pfad%" 2>nul
echo move "%Datei%" "%Pfad%"
goto :eof
P.S.: Irgendwie schade, dass das Ganze nicht auf meine Art durchgeführt werden darf:
ja es ist schade, daß dein Script nicht so arbeitet, wie ich es möchte. Das es "nicht auf deine Art durchfeführt werden darf" ist nicht dein Fehler, sondern der des DIR-Befehls dir /b /s /o:N, der nicht so arbeitet, wie ich will!
Der Befehl:
Das Ergebnis in einem leeren Zielordner listed sich etwa so im zunächst leeren Zielordner im WinExplorer, wenn es geschrieben wird:
Deine umlagern.bat $Vers1.0 liefert diese Reihenfolge in einen zuvor leeren Zielordner, der im WindowsExlorer angezeigt ist
cache\
Temp\
(Temp\temp1.tmp)
(Temp\temp2.tmp)
(Temp\temp3.tmp)
Archive\
(Archive\Archiv1.zip)
(archive\Archiv2.arc)
(Archive\Archiv3.rar)
Ainedatei.jpg
beinedatei.txt
ceinedatei.rtf
Dokument.doc
EineDateii.png
rtedatei.exe
sortierteDatei.lst
VierteDatei.ext
ztedatei.ext
Thumbnails\
(Thumbnails\thumbnail1.ext)
(Thumbnails\thumbnail2.ext)
(Thumbnails\thumbnail3.ext)
(Thumbnails\thumbnail4.ext)
MeineNeuenDateien\
(MeineNeuenDateien\neue Datei1.ext)
(MeineNeuenDateien\neue Datei2.ext)
Arbeit\
Welt\
nocheinordner\
intertnet\
Briefe\
Aschenputtel\
Die in Klammern () gesetzten Teile sieht man in dem Ordnerfenster des explorers noch nicht.
Der Befehl dir /b /s gibt sie aber in der Reihenfolge auch so aus.
Ich möchte aber, daß die Ordner auch schon in Sortierte Reihenfolge angelegt werden. Aber nicht nach Datum der Erstellung des Quellordners, sondern alphabethisch.
Dein erstes vorgeschlagenes Script (umlagern.bat von mir genannt) funktioniert relativ gut in deinem Sinne (mit hartcodierten Pfaden). und scheiterte nur an blöden Namen mit "!" und "%" drin, wie mein eigenes Script auch.
Dein letztes Sript unverändert copiert als umlagern3.bat benutzt ergibt folgen de Rückmeldung:
md "D:\Programme\3Dto3D\html_help\images\"
move "O:\Programme_D\Programme\3Dto3D\html_help\images\sample_3ds.jpg" "D:\Programme\3Dto3D\html_help\images\"
md "D:\Programme\3Dto3D\html_help\images\"
move "O:\Programme_D\Programme\3Dto3D\html_help\images\sample_pov.jpg" "D:\Programme\3Dto3D\html_help\images\"
Drücken Sie eine beliebige Taste . . .
Und das liegt an der Verwendung von TYP=jpg und weil direkt in \html_help\ kein *.jpg zu finden war.
Für meine Zwecke kann ich das aber auf TYP=* ändern, oder TYP weglassen. Ist also nicht wirklich das Problem.
Verwende ich dein Script in deiner ersten Version funktioniert es weitgehend gut, solange ich die Pfade direkt in der Batch im
Aber eben in oben geschilderter Reihenfolge der nicht sortierten Ordnernamen..
Es geht mir doch nicht darum deine Kometenzen in Frage zu stellen!!!
Ich bin dir dankbar dafür, das du versuchst eine mögliche Lösung anzubieten!!! und dafür Zeit opferst darüber nachzudenken. Selbst wenn du "Streit mir mir suchst" bist du bereit Zeit für etwas zu opfern, das du auch einfach ignorieren könntest.
Wenn aber deine Lösungsansätze nicht genau das erfüllen, was ich möchte, dann frage ich eben nach, wie ich Fehler in meinem Script verbessern kann. Und solange es mir nicht gelingt mit entsprechenden Verzweigungen in meiner Batch zu automatisieren, gehe ich dem umständlichen Weg mir Zwischenergebnisse in Arbeitsdateien im Editor anzeigen zu lassen um sie manuel zu korrigieren.
Grüße
bastla
P.S.: Und falls Du wirklich wolltest, dass mein letztes Script die Befehle nicht nur anzeigt, sondern auch ausführt, solltest Du die beiden "
echo
" am Beginn der Zeilen 12 und 13 entfernen ...Wenn Du tatsächlich diesen Eindruck hast, kann ich Dich beruhigen - die (vermeintliche) "Suche" ist hiermit
beendet.
Du die beiden "
echo
" am Beginn der Zeilen 12 und 13 entfernen ...Also egal ob in deinem oder meinem script, wenn die übergebenen Pfade Leerzeichen enthalten ist es problemärmer, die im Script einzutragen. Soweit sind wir uns wohl einig.
Nun habe ich die Idee dein Script, nennen wir es "umlagern.bat", zu verwenden und etwas abzuändern, damit ich meinem ziel näherkomme.
REM umlagern.bat
@echo off & setlocal
REM made by bastla from administrator.de 02.10.2010
set "Typ=*"
set "Basis=%~1"
set "Ziel=%~2"
for /f "delims=" %%i in ('dir /s /b /on "%Basis%\*.%Typ%"') do set "Pfad=%Ziel%%%~dpi" & set "Datei=%%i" & set "Quell=%%~dpi" & call :ProcessFile
pause
goto :verarbeiten
:ProcessFile
call set "Pfad=%%Pfad:%Basis%=%%"
call set "QPfad=%%Datei:%%~dpi"
echo md "%Pfad%" >>MakeDirs.txt
echo move "%Datei%" "%Pfad%" >>MoveList.txt
echo rd "%Quell%" >>rdQuelle.txt
goto :eof
:verarbeiten
sort MakeDirs.txt /O MakeDirs.bat
sort MoveList.txt /O MoveList.bat
sort /R rdQuelle.txt /O rdQuelle.bat
call MakeDirs.bat
call MoveList.bat
call rdQuelle.bat
rm makedirs.*
rm movelist.*
rm rdquelle.*
goto :eof
Das wäre die Endversion des Scriptes, doch vorher könnte ich mit
Und das die leeren QuellOrdner per Script gelöscht werden, erspart mir dies nachträglich von Hand zu tun.
Es bleiben lediglich die Ordner übrig, wo Dateien mit "blödem" Namen drin sind, die nicht verschoben wurden, weil "rd" nur leere Ordner löscht.. (Also wo "!" oder "%" im Namen ist.) Die muß ich dann eben noch mit dem WinExplorer nachschieben, aber nicht mehr hunderte Ordner einzeln durchsuchen.
Wobei "Sofort Lesen!.txt" wird mit deinem Script verschoben, weil keine Variablenverarbeitung mit "!" erfolgt, aber "neues%20Bild.jpg" bleibt liegen, und auch nur der "Neue Ordner" übrig, in den ich diese beiden zum Testen anlegte.
Aber da hätte ich noch eine Frage:
Je nach Menge von Dateien in einem Ordner, werden teils hunderte gleicher Zeilen erzeugt in MakeDirs.bat und rdQuelle.bat.Beispiele (nur kurze, weil sinnlos hier tausende Zeilen lange Ausgaben zu posten):
(MakeDirs.bat)
md "x:\test\PFY\"
md "x:\test\PFY\XtraDocF\"
md "x:\test\PFY\XtraDocF\"
md "x:\test\PFY\XtraDocF\"
md "x:\test\PFY\XtraDocF\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
md "x:\test\PFY\XtraDocF\Images\"
if not exist "x:\test\PFY\XtraDocF\Images\" md "x:\test\PFY\XtraDocF\Images\"
oder
(rdQuelle.bat)
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\Images\"
rd "F:\PFY\XtraDocF\"
rd "F:\PFY\XtraDocF\"
rd "F:\PFY\XtraDocF\"
rd "F:\PFY\XtraDocF\"
rd "F:\PFY\"
Im Original leitest du die Fehlermeldungen in der FOR-Schleife ja mit " 2>nul" ins "Nichts" um.
Ein Vorteil von Deinem Script scheint nämlich zu sein, daß ich im umgekehrten Fall , wo :\test\ aus dem Zielpfad rausgeschnitten werden sollte, nichts extra machen muß!
Bei
Und genau dieser unerwünschte Effekt passiert bei deinem Script nicht!
Prima!!!
Allerdings bekomme ich jetzt viele Meldungen:
Ansonsten läuft das jetzt recht gut. Ich muß nur diese beiden Zeilen wenigstens so abändern:
echo if not exist "%Pfad%" md "%Pfad%" >>MakeDirs.txt
...
echo if exist "%Quelle%" rd "%Quell%" >>rdQuelle.txt
<code type="plain>set "Basis=%~1"
entstehen nicht mehr und nicht weniger Probleme als durch eine Zuweisung einer Konstanten.
BTW: Natürlich lassen sich mit "
rd
" auch nicht-leere Ordner löschen (siehe "rd /?
") - ob das auch sinnvoll wäre, musst Du entscheiden.Und: Zum Löschen leerer Ordner gibt es nebenan einen Ansatz ...
findstr /i /c:"%Pfad:\=\\%" MakeDirs.txt>nul||echo md "%Pfad%">>MakeDirs.txt
2>nul
"-Variante ausreichend.Grüße
bastla
P.S.: Deine Batch-Zeile 14 erzeugt eine Variable, die in weiterer Folge nicht verwendet wird, und das "
rm
" der Zeilen 27 bis 29 heißt in Batch "del
" ...Hallo bastla,
danke für deine Antwort.Das ich in meine Batchdateien (oder andere) reinschreibe, worauf sie basieren, dient mir selber zur Orientierung wo ich etwas her habe. Ist also mehr so 'ne Art "Quellennachweis" für mich selber. So weiß ich auch Wochen, Monate, Jahre später noch, woher hilfreiche Infos kamen. -- oder woher falsche..
Gratulation! "Dein" Script funktioniert mit meinen Modifikationen jetzt besser als mein altes!
Also herzlichen Dank für DEINE Hilfe!
(Ja du hast Recht "rm" mußte "del" heißen... doch scheinbar funktioniert das "rm" auch?!?! oder doch nicht?)
"Sofort lesen!.txt" wurde verschoben, aber
"ein%20Bild.jpg" (oder sowas) bleibt unverschoben liegen!!!
In meinem Script "moveto.bat" versuchte ich Zeichenkettenbearbeitung, (set str=!str:~0,-2! ) (die ich woanders las), mit "delayedExpansion" und "!" im Namen ging nicht mehr! Es ergab "Müll"-Zeilen. Sowas wie "Pfad\str" statt "Pfad\dateiname.ext".
"rm" gibt es wohl wirklich nicht bei MSDOS. Aber beim Testen war das egal. Jetzt verwende ich "del".
Dann müßte ich auch Zeile 17 so ähnlich ändern, von
Reicht es, wenn ich diese Zeilen einfach mit deinem Vorschlag ersetze??? Oder wo baue ich diese Zeile(n) ein?
Bei Ordnerstrukturen mit 100.000 Dateien oder mehr kann das eine Rolle spielen! besonders wenn mehrere hundert Dateien in einem Ordner vorkommen und ebensooft unnötig der Befehl "makedir schon vorhandenen Ordner" aufgerufen wird.
Bei 5-10 Aufrufen vielleicht noch nicht spürbar. Bei Ordnern mit 500 Dateien aber schon. (Manch Bilderordner bei mir hat rund 500 Bilder! Der Ordner \Ahead\NeroDB\ enthält 1288 Objekte (49,1 kb). = 1287 überflüssige Befehle der Art "md \Ahead\NeroDB" oder "rd \Ahead\NeroDB". 1287 Sekunden gespart sind 21 Minuten Verarbeitungszeit weniger!)
Im Script in der aktuellen Version unterdrücke ich ja die Fehlermeldungen der "movelist.bat" noch nicht.
So kommen in dem Bereich noch viele Meldungen:
Nachdem ich das neue Script erfolgreich auf kleinere Ordnerstrukturen angewendet hatte, schickte ich es über einen Ordner mit 4 GB Inhalt.
Aufgrund der vielen "Zugriff verweigert" Meldungen sind nicht alle Ausgaben mehr im DOS-Fenster sichtbar.
Um den Zeitaufwand zu sehen, verwendete ich am Anfang des Scriptes noch
Das Ende dieser Ausgabe sieht so aus:
...
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Zugriff verweigert
Verschieben beendet.
Loesche Quellordner...
entferne Arbeitsdateien...
fertig...
Startzeit: 17:28:51,20
Endzeit: 18:54:37,20
Arbeitszeit: 18:54:37,23:-17:28:51,20
Das Ergebnis dieser Aktion: im Windows-Explorer auf "Eigenschaften des Ordners" geklickt:
Größe auf Datenträger: 4,5 MB (4.718.492 bytes)
Inhalt: 144 Dateien (333 Ordner)
Es sind 16 Haupt-Ordner übrig geblieben, teilweise mit wenigen auch leeren?!?! Unterordnern!
Allerdings hatten diese eigentlich leeren Ordner ein blödes "Nicht verschiebbar-flag" für die Defragmentierung.
Ich hatte diese Ordner-Struktur zuvor mit
Bescheuerterweise haben etwa tausend Ordner auf meiner Programme Partition ein "Nicht verschiebbar bei defragmentierungs-Flag", obwohl es keine Systemdateien sind. Diese liegen breit vertreut auf der Platte und verhindern jede Defragmentierung, weil tausende nicht nutzbare Lücken bleiben. Teilweise sind das Ordner wie "\Eigene Dateien\gespeicherte_html_Seite-Dateien\ads_frame\", teilweise Ordner wie "\Programme\Corel\Corel Paint Shop Pro Photo X2\Languages\EN\PCUUI\", die eigentlich leer sind!!!
Es gibt aber auch Dateien, die sich nicht verschieben ließen:
Allein im Corel-Ordner sind etwa 34,3 kb Fremdsprachen-Müll in 24 Dateien übrig geblieben, die etwa 760 kb auf Daztenträger belegen. (Vorher kopiert mit AlwaysSync)
OK. die kann ich getrost löschen in der Quelle... Ich brauche kein Spanisch,Italienisch,Französisch,Portugisisch... = Datenmüll, der die Festplatten verstopft.
Insgesamt sind noch übrig in \Programme\ noch 163 kb in 144 Dateien, die 4,5 MB auf Datenträger belegen! (FAT32)
Aber auch Ordner wie "O:\Programme_D\Programme\CyberLink\PowerDVD\Images" ließen sich nicht mit rd löschen, obwohl sie leer sind! (Angelegt mit xcopy /T, nicht mit script-Befehl "md O:\Ordnerstruktur" vor dem ersten Verschieben)
In
MyHeritage hinterlies ettliche Dateien mit "%63" im Namen....
Bei mir ist in den Ordneroptionen ausgeschalten "versteckte und Systemdateien ausblenden" und eingeschaltet "Alle Dateien und Erweiterungen anzeigen"!
Na gut. jetzt kann ich im Windows-Explorer alle übrig gebliebenen Hauptorder mit ALT+D+I in den Eigenschaften sehen ob sie 0 byte und 0 Dateien sind und gleich löschen. Wo nochwas drin ist muß ich reigehen und schauen, ob ich es behalten will.
Ich hatte meine 32 GB große, nicht mehr defragmentierbare Programme-Partition auf einen externen USB-Datenträger verschoben, und schiebe die Dateien nun mit Hilfe der Scripte zurück. Die Windows Kopieren-Verschieben-Funktion trug diese "nicht verschiebbar Flags" immer mit! Nun ist der externe Datenträger nicht mehr richtig defragmentierbar, bis ich die leeren Restordner lösche.
Ich bekam diese beschissenen "nicht verschiebbar"-Flags erst weg, als ich die nun leere Partition D:\ formatierte und mit den Scripts den Inhalt zurück schob. (gearbeitet von einer UBCD4WIN)
Andererseits kann ich dieses Script in modifizierter form (copy statt move) nun auch für die sortierte Befüllung von SD-Karten für digitale Bilderrahmen oder MP3-Player verwenden!