fullpanic
Goto Top

Batch - Dateiname bis zu einem bestimmten Zeichen einlesen und ein Ordner damit erstellen

Hallo,
ich versuche eine Batch-Datei zu erstellen, welche den Dateinamen bis zum Zeichen " - " einliest und damit einen Ordner erstellt. Mit dem selben eingelesenen Dateinamen werden dann die Dateien in die Ordner verschoben bis alle Dateien sortiert sind.

Muster:

Datei: xyz - egal_was.endung
Datei: opq - egal_was.endung

Ordner "xyz" wird erstellt
Ordner "opq" wird erstellt

Alle Dateien die jetzt "xyz" enthalten sollen nun in den Ordner xyz und alle wo "opq" enthalten in den Ordner "opq" verschoben werden.
Bsp:
xyz - egal_was.endung --> xyz
opq - egal_was.endung --> opq

--> = verschieben

Content-ID: 170880

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

Ausgedruckt am: 24.11.2024 um 06:11 Uhr

60730
60730 03.08.2011, aktualisiert am 18.10.2012 um 18:47:45 Uhr
Goto Top
moin,

das ist ein klassischer Fall für eine For Schleife.

Dazu soltest du entweder über das Tut vom Friemler oder über for /? oder über die Suchfunktion sehr vieles finden.

Da du die Batch ja selber schreiben willst, lass ich dir den Vortritt.

Wenns wider erwarten doch hakt, dann....

Gruß
Skyemugen
Skyemugen 03.08.2011 um 14:53:31 Uhr
Goto Top
Aloha,

ich versuche eine Batch-Datei zu erstellen

Gut, also geben wir dir nur Tipps & Hinweise face-wink

also da wären zum Beispiel:
  • pushd "E:\Das_Verzeichnis_der_Dateien" da ich hier nichts von mehreren Verzeichnissen oder Unterverzeichnissen lese
  • for /f "delims=- tokens=1" %%s in ('dir /b /a-d') do set "Name=%%s" um den Dateinamen einzulesen bzw. nur das vor dem Minus
  • set "Ordner=%Name:~0,-1%" um das Leerzeichen vor dem Minus wegzubekommen
  • if not exist "%Ordner%" md "%Ordner%"
  • popd

Oder noch einfacher: Die Suche hier im Forum.

greetz André

P.S.: Das ist kein voll funktionierendes Skript, da fehlt noch so einiges aber du wolltest die ja selbst erstellen also werfe ich mal nur ein paar hilfreiche Brocken hin. - Man kann auch ganz anders vorgehen/anfangen face-wink
bastla
bastla 03.08.2011 um 15:47:30 Uhr
Goto Top
@Skyemugen
Ich hätte ja noch gefragt, ob der gesuchte Teil Leerzeichen enthalten kann ...

Grüße
bastla
Skyemugen
Skyemugen 03.08.2011 um 15:56:41 Uhr
Goto Top
Zitat von @bastla:
@Skyemugen
Ich hätte ja noch gefragt, ob der gesuchte Teil Leerzeichen enthalten kann ...

Aloha bastla, na dann frag' doch face-wink

Man kann auch ganz anders vorgehen/anfangen
Ich gehe einfach erst einmal davon aus, dass dort welche vorkommen können.

Er wollte imho erst einmal nur Tipps, wenn man mit Tipps schon alles erdenkliche abdecken will, können wir ja auch gleich ein komplettes Skript schreiben :P

Soll sich der TE erst einmal wieder melden ^_^

greetz André

edit @bastla: stimmt auch wieder, er gibt ja explizit " - " vor, wer weiß, ob das wirklich das erste Minus ist, naja soll er sich mal melden wieder ^_^
bastla
bastla 03.08.2011 um 16:06:24 Uhr
Goto Top
Hallo Skyemugen!

Wenn von allen Eventualitäten auszugehen wäre, müsste ja auch noch ein "-" (ohne Leerzeichen davor und/oder danach) im ersten Teil einkalkuliert werden ... face-wink

[Edit] Allerdings ist
set "Name2=%Name:* - =%"  
call set "Ordner=%%Name: - %Name2%=%%"  
(und dann auch noch in einer Schleife) vermutlich nicht mehr wirklich "anfängertauglich" ... face-wink
[/Edit]

Grüße
bastla
fullpanic
fullpanic 03.08.2011 um 16:57:02 Uhr
Goto Top
Hi,
erstmal danke für eure schnellen Antworten und Hilfen.

Also bisher hab ich das hier geschafft:

@echo off

for /f "delims=- tokens=1" %%s in ('dir /b /a-d') do set "Name=%%s"
set "Ordner=%Name:~0,-1%"

if not exist "%Ordner%" md "%Ordner%"
move "%%s" "%Ordner%"

pause

Leider weiß ich noch nicht wieso es immer alle Dateien in den neu erstellten Ordner verschiebt. Was mir noch eingefallen ist, das ich nicht beachtet hab, das einige Dateien im vorderen Teil der Beschriftung Bsp. erster_teil - zweiter_teil.endung auch Leerzeichen haben.

Also folgende Probleme sind noch zu lösen:
1. Es wird immer nur ein Ordner erstellt mit dem Namen, und andere Dateien werden nicht berücksichtigt
2. Alle Dateien werden in den Ordner verschoben
3. Das erstellen eines Ordner klappt nur bei einer bestimmten Datei mit der Benennung. Sobald man diese Datei entfernt, und meine test.bat startet heißt der erstellte Ordner test.ba

Vielen Dank für eure Hilfe
Hoffentlich klappts bald, ich will ungern hunderte von Liedern sortieren zu müssen. ^^

Gruß panic
60730
60730 03.08.2011 um 17:26:01 Uhr
Goto Top
moinsen
Zitat von @fullpanic:
Hi,
erstmal danke für eure schnellen Antworten und Hilfen.

Also bisher hab ich das hier geschafft:

@echo off
  • ganz schlechter start

for /f "delims=- tokens=1" %%s in ('dir /b /a-d') do set "Name=%%s"
  • klapper alles ab und wenn du fertig bist ist der letzte Treffer die Variable Name
set "Ordner=%Name:~0,-1%"
  • ist also immer der letzte Treffer

if not exist "%Ordner%" md "%Ordner%"
  • immer noch immer wieder der letzte Treffer
move "%%s" "%Ordner%"
  • ergo ganz klar, das er das macht, was du schreibst.

Hoffentlich klappts bald, ich will ungern hunderte von Liedern sortieren zu müssen. ^^

  • Lieder?
  • mp3?
  • richtig getaggte?
fullpanic
fullpanic 03.08.2011 um 17:32:33 Uhr
Goto Top
Hey,
nein, leider sind sie nicht richtig getaggt. Also muss ich das über den Namen so machen.
Ich versuchs heute Abend nochmal.

Mfg panic
bastla
bastla 03.08.2011 um 21:50:08 Uhr
Goto Top
... und außerdem:
Das erstellen eines Ordner klappt nur bei einer bestimmten Datei mit der Benennung. Sobald man diese Datei entfernt, und meine test.bat startet heißt der erstellte Ordner test.ba
... was ja auch nicht überraschen dürfte - es wird am ersten vorkommenden "-" geteilt; wenn kein "-" vorkommt, wird eben nicht geteilt ...

... und danach das letzte Zeichen (sollte eigentlich ein Leerzeichen sein) abgeschnitten.

Übrigens: Ein klassisches Beispiel dafür, dass es gut ist, Programm (nennen wir den Batch mal so face-wink) und Daten (ordnermäßig) zu trennen ...

Zu letzterem Thema: pushd / popd

Grüße
bastla
60730
60730 03.08.2011 um 23:33:41 Uhr
Goto Top
@ Bastla:

naja "überrascht" bin ich auch nicht wirklich...

Bis auf das zusätzliche Echo off und das weglassen von Push/popd sehe ich da nicht viel Eigenleistung.

Übrigens: Ein klassisches Beispiel dafür, dass es gut ist, Programm (nennen wir den Batch mal so face-wink) und Daten (ordnermäßig) zu trennen ...
Naja - streng genommen will er Dateien - bzw. deren Namen - die ein Zeichen (nennen wir es - ) beeinhalten anhand dieses Zeichens "teilen".
Der Wink mit dem Zaunpfahl sucht aber nach alles mit sosse und extra scharf... Apropos Zaunpfahl, das Winken mit demselben geht ganz schön auf die Arme...

dir /b /a-d *-*.*
Skyemugen
Skyemugen 04.08.2011 um 08:20:56 Uhr
Goto Top
Aloha ...

P.S.: Das ist kein voll funktionierendes Skript, da fehlt noch so einiges aber du wolltest die ja selbst erstellen also werfe ich mal nur ein paar hilfreiche Brocken hin.

Vielleicht sollte ich den Satz auf Chinesisch übersetzen, wird ja bestimmt bald Weltsprache und dann wird eventuell auch glasklar, dass man diese lustigen Zeilen nicht einfach c&p in einen code und glaubt, das läuft dann schon wie gewollt ...

ich versuche eine Batch-Datei zu erstellen

Dachte ich, dass dies bedeuten könnte: Ich habe ein wenig Ahnung von batch, aber hier benötige ich eure Hilfe

und nicht: baut mir was, ich c&p das dann und freue mich, da ich absolut keinen Plan hab, was da eigentlich passiert

Ist dir eigentlich klar, was die paar Zeilen nur machen?

Kurzgefasst: Du erhälst den letzten Treffer der Dateien, dieser wird gespalten, das letzte Zeichen entfernt, ein Ordner mit dessen ersten Part erstellt und sämtliche Dateien hineingeschoben aber das hast du wohl auch schon bemerkt ^_^

Dass da noch ein Unterprogramm fehlt, ist eine andere Sache face-wink

@t-mo

Nun, er hat auch
move "%%s" "%Ordner%"  
und
pause
hinzugefügt ^_^

Hätte er Eigeninitiative gezeigt, hätte er bereits mind. 5 Themen dieser Art im Forum gefunden und sich darauf berufen bzw. damit rumgespielt.

greetz André

P.S.: Keine Lust auf Rumgekasper heute ...
@echo off & setlocal
set "Pfad=E:\Skripte\Ablage\Test"  
pushd "%Pfad%"  
for /f "delims=- tokens=1,*" %%s in ('dir /b /a-d *-*.*') do call :Ablauf "%%s" "%%t"  
popd
pause
exit /b

:Ablauf
set "Name=%~1"  
set "Ordner=%Name:~0,-1%"  
if not exist "%Ordner%" md "%Ordner%"  
move "%~1-%~2" "%Ordner%"  
goto :eof

Ich gehe jetzt einfach mal davon aus, dass das Trennzeichen (Minus) nicht im ersten Teil vorkommt, da der TE diesbezüglich nichts weiter schrieb und dass Leerzeichen enthalten sein können, auch wenn mir das Beispiel des TE anhand _ weniger nach Leerzeichen aussieht face-wink
Wenn noch jemand Optimierungsvorschläge hat oder Einwände, dann her damit, hatte noch kein Frühstück heute ^_^
bastla
bastla 04.08.2011 um 10:15:33 Uhr
Goto Top
Hallo Skyemugen!

Das nenne ich mal rrrichtig rrresolut ... face-wink

... da will ich mich auch nicht lumpen lassen und spinne mal den Gedanken von oben weiter:
@echo off & setlocal
set "Pfad=E:\Skripte\Ablage\Test"  
set "DelimString= - "  

pushd "%Pfad%"  
for /f "delims=" %%i in ('dir /b /a-d "*%DelimString%*.*"') do set "Name=%%i" & call :ProcessFile "%%i"  
popd
goto :eof

:ProcessFile
call set "Name2=%%Name:*%DelimString%=%%"  
call set "Ordner=%%Name:%DelimString%%Name2%=%%"  
md "%Ordner%" 2>nul  
move %1 "%Ordner%"  
goto :eof
Die Idee ist, eine Trennung nicht nur anhand eines einzelnen Delimiter-Zeichens durchzuführen, sondern einen String (hier: "Leerzeichen Minus Leerzeichen") verwenden zu können (braucht man/frau ja dann doch gelegentlich mal wieder) ...

Grüße
bastla

[Edit] "Delimiter-String" in Variable ausgelagert [/Edit]
Skyemugen
Skyemugen 04.08.2011 um 10:38:33 Uhr
Goto Top
Aloha bastla,

hmm ... interessant ... und immer wieder verwirrt mich schon der Anblick, haha.

Muss ich auch mal verarbeiten, diese Art von Verarbeitung ^_^.

Also, in Name2 wird der sämtliche erste Teil, einschließlich der Trennfolge durch nichts ersetzt, was mich verwirrt ist, warum für Ordner nicht umgekehrt äquivalent "Ordner=%%Name:%DelimString%*=%%" funktioniert *grübel*
E:\Skripte\Ablage\Test>call set "Ordner=%Name: - *=%"
E:\Skripte\Ablage\Test>echo abc - testde.xyz

Eventuell kannst du mich da erleuchten, bastla? face-wink

greetz André

P.S.: Kann das eigentlich auch ohne call geschehen? was genau läuft da eigentlich ab, so glasklar war mir das nie
bastla
bastla 04.08.2011 um 10:58:18 Uhr
Goto Top
Hallo Skyemugen!
warum für Ordner nicht umgekehrt äquivalent "Ordner=%%Name:%DelimString%*=%%" funktioniert *grübel*
Diesbezügliche Beschwerden (und Du hast ja mit der Überlegung völlig Recht face-wink) bitte direkt an die noch überlebenden zuständigen MS-Praktikanten ...

... mit anderen Worten (aus der "set"-Onlinehilfe):
Wenn "str1" mit einem Sternchen beginnt, steht "str1" für alles zwischen dem Anfang der erweiterten Ausgabe bis zum ersten Auftreten des übrigen Abschnitts von "str1".
"Wenn "str1" mit einem Sternchen endet ..." ist nun mal nicht vorgesehen / implementiert ...
"call" ruft eine weitere CMD-Instanz auf, in welcher die unter einfachen Prozentzeichen stehenden Variablen aufgelöst werden - die unter doppelte Prozentzeichen gesetzten Variablen werden erst bei der Rückkehr in die aktuelle Instanz in Werte umgewandelt, wobei die Einfach-Prozentzeichen-Variablen(-Werte) hier dann schon "Konstanten" sind - damit wird zB mit einem Inhalt "opq - egal_was.endung" in %Name% durch
call set "Name2=%%Name:*%DelimString%=%%"
eigentlich ein
set "Name2=%Name:* - =%"
- wobei aber %DelimString% eben eine Variable sein konnte (was der eigentliche Sinn dieser Konstruktion ist) - und in weiterer Folge dann der Inhalt "egal_was.endung" in %Name2% ...

Die (von mir, nicht zuletzt wegen der Nebenwirkungen hinsichtlich enthaltener "!", weniger gern verwendete) Alternative dazu wäre "delayedexpansion" - damit sähe das dann so aus:
set "Name2=!Name:*%DelimString%=!"
Grüße
bastla
mathe172
mathe172 04.08.2011 um 11:05:01 Uhr
Goto Top
Hallo,

Eventuell kannst du mich da erleuchten, bastla
Vielleicht kann ich ja unserem Bastla etwas Arbeit ersparen face-wink

Kann das eigentlich auch ohne call geschehen?
Das call bewirkt, dass der Befehl zweimal ausgewertet wird. Also:

call set "Name2=%%Name:*%DelimString%=%%"
wird zu
"Name2=%Name:* - =%" 
und dann noch einmal verarbeitet. Das sollte auch mit delayedexpansion gehen...

Was das andere angeht: Mit der ersten Zeile (call set "Name2=%%Name:*%DelimString%=%%") findet er alles nach dem Delimsstring raus und mit call set "Ordner=%%Name:%DelimString%%Name2%=%%" ersetzt er dann diesen Rest und den Delimstring durch nichts.
Ich nehme mal an, dass er das macht, um alles ab dem ersten DelimString zu löschen

Mathe172
[Edit: Warum mach ich mir eigentlich noch Tipparbeit ... face-wink]
bastla
bastla 04.08.2011 um 11:11:08 Uhr
Goto Top
@mathe172
Warum mach ich mir eigentlich noch Tipparbeit ... face-wink
Aufgrund Deiner Erklärung könnte ich mir diese Frage jetzt auch stellen ... face-smile

Grüße
bastla
Skyemugen
Skyemugen 04.08.2011 um 11:20:35 Uhr
Goto Top
Aloha bastla,

hm, ob Bill sich auch meiner Beschwerde annehmen wird? face-wink
Ahja, richtig, die doppelten Prozentzeichen müssen ja sein, weil ich das ganze ja weiterleite und wieder zurückleite, ist ja prinzipiell der Aufbau wie wir ihn hier hauptsächlich verwenden, um delayedexpansion nicht anwenden zu müssen.

Die Verarbeitung unter Anwendung von DLXP (oder nenn' ich es doch nur DEP hmm... müssen uns mal auf eine Abk. dafür einigen, das Ausschreiben ist immer so lang *gg*) war mir klar, deine angesprochenen „ Nebenwirkungen” waren mir nicht bewusst aber mit einem einfachen Test, das Minus durch ein Ausrufezeichen zu ersetzen, war direkt sichtbar, dass der Dateiname dann nicht mehr korrekt genutzt wird, was hier zwar dennoch zu einer korrekten Ausgabe des Ordnernamens führt aber das ! wegrationalisiert, was natürlich unschön ist.

greetz André

@mathe, was genau dort mit dem DelimString und Kürzungen/Ersetzungen passiert, ist mir klar face-wink nur die Logik, warum nicht auch umgekehrt, fehlte mir eben ^_^
bastla
bastla 04.08.2011 um 11:54:33 Uhr
Goto Top
@Skyemugen
was hier zwar dennoch zu einer korrekten Ausgabe des Ordnernamens führt
... aber auch nur, wenn nicht schon im ersten Teil ein "!" enthalten ist ...
aber das ! wegrationalisiert, was natürlich unschön ist.
Das kommt noch besser, wenn es zwei "!" gibt - der Teil dazwischen wird dann ja als Variablenname interpretiert; wenn es die Variable nicht gibt, wird auch nix eingesetzt und der Teil verschwindet (samt den "!"), wenn aber die Variable zufällig vorhanden sein sollte, steht anstelle von "!Teil dazwischen!" plötzlich "Inhalt der Variablen" da ...

Grüße
bastla
fullpanic
fullpanic 04.08.2011 um 13:35:12 Uhr
Goto Top
Hi,
danke euch, das ihr mir geholfen habt. Die Codes von Skyemugen und bastla funktionieren.

Nun zu dem was ihr geschrieben habt. Ich weiß selber das ich nicht viel Ahnung von Batch und Shell habe, das kommt noch alles, da ich mich damit intensiver beschäftigen will. Natürlich habe ich mir Arbeit gemacht, ich habe sehr viel an den Tipps von Skyemugen rumgebastelt, leider ohne Erfolg. Da ich auch gestern nicht viel Zeit hatte, konnte ich auch nicht viel erreichen, vorallem nicht wenn man so wenig Erfahrung in dem Bereich hat.

Vielen Dank für eure Hilfe
ihr habt mir einiges an Sortierarbeit erspart.

Gruß fullpanic

PS: nächstes Schuljahr werde ichs besser können, da ab September bei mir auf der Schule dieses Fach hinzukommt und als Pflichtfach gilt.
Skyemugen
Skyemugen 04.08.2011 um 14:24:10 Uhr
Goto Top
Zitat von @fullpanic:
PS: nächstes Schuljahr werde ichs besser können, da ab September bei mir auf der Schule dieses Fach hinzukommt und als Pflichtfach gilt.

Aloha,

hm also ich habe batch nur durch eines „gelernt“ : Administrator.de *lach* Praxisbeispiele und Anfragen der User sowie bastlas, Bibers und Friemlers und auch mal T-Mos haha Erklärungen, Hinweise etc. haben da ganz ihre Arbeit getan.
Und während man so vor sich hin bätschelt, lernt man hier und da immer wieder etwas dazu.

Pflichtfach pfff, soweit kommt's noch *gg*

greetz André
Lochkartenstanzer
Lochkartenstanzer 07.08.2011 um 19:41:45 Uhr
Goto Top
Ich würde das unter Windows mit cygwin lösen:

echo >tempfile.sh ; ls  | gawk -F "-" ' { print $1} ' | xargs -l1 -I XXXX echo "mv XXXX-* XXXX" >>tempfile.sh ; source tempfile.sh 

Sicher noch verbesserungswürdig, aber sollte den Job erledigen, und das ohne "for"-Schleife. face-wink
Skyemugen
Skyemugen 08.08.2011 um 07:56:03 Uhr
Goto Top
Aloha LKS,

bekommst du eigentlich Provision für das ständige Verlinken und Funktionsdarstellen von cygwin?

Wo bleibt denn bei derartigen kurzen Einzeiler der Spaß beim Entwickeln?

greetz André
Lochkartenstanzer
Lochkartenstanzer 08.08.2011 um 10:59:19 Uhr
Goto Top
Zitat von @Skyemugen:

bekommst du eigentlich Provision für das ständige Verlinken und Funktionsdarstellen von cygwin?

Nee, aber es ist einfacher, wenn ich den Link gleich mit angebe, als wenn ich den erst auf Nachfrage liefere.

Wo bleibt denn bei derartigen kurzen Einzeiler der Spaß beim Entwickeln?

Ich bin halt ein "fauler" Mensch und tippe ungern viel. Daher versuche ich mehr oder weniger alles mit einem Einzeiler zu erschlagen. face-smile Das ist dann mein Spaß, alles in eine Zeile zu packen.