Tokens-Dateinamenzerlegungsproblem (Variablen werden überschrieben?)
Hallo zusammen. Ich habe hier durch vielerlei Anregungen eine Batch halbwegs zum Laufen gebracht, die mir als Ergebnis aber immer nur die Werte der letzten Datei aus einem Ordner wiedergibt, wobei eigentlich alle berücksichtigt werden sollen. Da ich absoluter Laie bin (was man am Code vermutlich auch unschwer erkennen kann) hoffe ich auf eure Hilfe.
Aufgabe: Die Batch soll die Dateinamen aller Mediendateien in einem Ordner, in dem sie sich selbst befindet (ist aber kein Muss, meinetwegen darf sie ruhig eine Ebene hochrutschen) "zerstückeln" und zusammen mit der jeweiligen Dateigröße in eine XML zur Weiterverarbeitung schreiben.
Mein bisheriger Versuch sieht so aus:
Das Ganze liefert mir eigentlich schon den gewünschten Aufbau, nur leider schreibt er nur die Ergebnisse der letzten Datei hinein. Ich nehme also an, dass er die Variablen %%i-%%n überschreibt. Nur weiß ich leider nicht, wo ich da ansetzen soll. Außerdem wäre es nett, wenn ihr mir einen Tipp zum Schreiben des jeweiligen Dateinamens in die xml geben könntet, der sträubt sich auch noch. Vielen Dank schon mal.
Aufgabe: Die Batch soll die Dateinamen aller Mediendateien in einem Ordner, in dem sie sich selbst befindet (ist aber kein Muss, meinetwegen darf sie ruhig eine Ebene hochrutschen) "zerstückeln" und zusammen mit der jeweiligen Dateigröße in eine XML zur Weiterverarbeitung schreiben.
Mein bisheriger Versuch sieht so aus:
@echo off
@setlocal enabledelayedexpansion
REM +++ Dateinamen zerlegen
FOR /f "delims=_ tokens=1-6" %%i in ('Dir /b C:\MyMedia\Test\*_*_*_*_*_*.*') do (
set varGroup=%%i
set varAlbum=%%j
set varTitle=%%k
set varNr=%%l
set varBitrate=%%m
set varType=%%n)
REM +++ Dateigrösse ermitteln
for /f "delims=" %%i in ('Dir /b C:\MyMedia\Test\*_*_*_*_*_*.*') do (
set varSize=%%~zi)
REM +++ XML Header schreiben
ECHO ^<?xml version="1.0" encoding="UTF-8"?^> >test.xml
ECHO ^<request^> >>test.xml
REM +++ XML schreiben
FOR /f "delims=_ tokens=1-6" %%i in ('Dir /b C:\MyMedia\Test\*_*_*_*_*_*.*') do (
ECHO ^<item type="file"^> >>test.xml
ECHO ^<filename^>%Dateiname%^</filename^> >>test.xml
ECHO ^<group^>%varGroup%^</group^> >>test.xml
ECHO ^<album^>%varAlbum%^</album^> >>test.xml
ECHO ^<title^>%varTitle^</title^> >>test.xml
ECHO ^<nr^>%varNr%^</nr^> >>test.xml
ECHO ^<type^>%varType%^</type^> >>test.xml
ECHO ^<bytes^>%varSize%^</bytes^> >>test.xml
ECHO ^</item^> >>test.xml
)
REM +++XML Footer schreiben
ECHO ^</request^> >>test.xml
goto :eof
:End
Endlocal
Das Ganze liefert mir eigentlich schon den gewünschten Aufbau, nur leider schreibt er nur die Ergebnisse der letzten Datei hinein. Ich nehme also an, dass er die Variablen %%i-%%n überschreibt. Nur weiß ich leider nicht, wo ich da ansetzen soll. Außerdem wäre es nett, wenn ihr mir einen Tipp zum Schreiben des jeweiligen Dateinamens in die xml geben könntet, der sträubt sich auch noch. Vielen Dank schon mal.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 170688
Url: https://administrator.de/contentid/170688
Ausgedruckt am: 18.11.2024 um 05:11 Uhr
11 Kommentare
Neuester Kommentar
Hallo Sodele,
das sollte so gehen (ungetestet):
Daten, die man ermittelt hat, sollte man auch direkt verarbeiten, nicht erst 10 Zeilen weiter unten, nachdem die Schleife schon beendet ist. .
Die Ausgabeumleitung bei
In Zeile 17 wird nur der Dateiname ohne Erweiterung in die XML-Datei geschrieben. Wenn es beides sein soll, schreibe statt
Gruß
Friemler
[EDIT]
Code zur Erhöhung der Ausführungsgeschwindigkeit auf die Blockwrite-Methode von Mathe geändert.
[/EDIT]
[EDIT2]
Bugfix: Der Dateiname wurde falsch zerlegt.
[/EDIT2]
das sollte so gehen (ungetestet):
@echo off & setlocal
set "Output=C:\test.xml"
REM +++ XML Header schreiben
> "%Output%" ECHO ^<?xml version="1.0" encoding="UTF-8"?^>
>>"%Output%" ECHO ^<request^>
pushd "C:\MyMedia\Test"
REM +++ Dateinamen ermitteln
(FOR /f "delims=" %%a in ('dir /b "*_*_*_*_*_*.*"') do (
REM +++ Dateinamen zerlegen
FOR /f "delims=_. tokens=1-6" %%i in ("%%a") do (
ECHO ^<item type="file"^>
ECHO ^<filename^>%%~na^</filename^>
ECHO ^<group^>%%i^</group^>
ECHO ^<album^>%%j^</album^>
ECHO ^<title^>%%k^</title^>
ECHO ^<nr^>%%l^</nr^>
ECHO ^<bitrate^>%%m^</bitrate^>
ECHO ^<type^>%%n^</type^>
ECHO ^<bytes^>%%~za^</bytes^>
ECHO ^</item^>
)
))>>"%Output%"
popd
REM +++XML Footer schreiben
>>"%Output%" ECHO ^</request^>
Daten, die man ermittelt hat, sollte man auch direkt verarbeiten, nicht erst 10 Zeilen weiter unten, nachdem die Schleife schon beendet ist. .
Die Ausgabeumleitung bei
ECHO
-Befehlen sollte man immer vor das ECHO
schreiben, das vermeidet Fehlfunktionen des Codes, die tückischerweise nur unter bestimmten Umständen auftreten. Das hat aber nichts mit Deinem Fehler zu tun.In Zeile 17 wird nur der Dateiname ohne Erweiterung in die XML-Datei geschrieben. Wenn es beides sein soll, schreibe statt
%%~na
einfach %%a
.Gruß
Friemler
[EDIT]
Code zur Erhöhung der Ausführungsgeschwindigkeit auf die Blockwrite-Methode von Mathe geändert.
[/EDIT]
[EDIT2]
Bugfix: Der Dateiname wurde falsch zerlegt.
[/EDIT2]
Hallo,
du musst nach dem setzten der Variablen (Z6-Z11) jedesmal Daten in die XML schreiben.
Etwa so:
(Ungetestet)
MfG,
Mathe172
[Edit: Das war so klar dass wieder jemand schneller ist...]
du musst nach dem setzten der Variablen (Z6-Z11) jedesmal Daten in die XML schreiben.
Etwa so:
@echo off
REM +++ XML Header schreiben
(ECHO ^<?xml version="1.0" encoding="UTF-8"?^>
ECHO ^<request^>
)>"test.xml"
REM +++ Alle Dateien abarbeiten (Schau mal "/s" bei "dir /?" and)
for /f "delims=" %%a in ('Dir /b C:\MyMedia\Test\*_*_*_*_*_*.*') do (
REM +++ XML schreiben
FOR /f "delims=_ tokens=1-6" %%i in ("%~a") do (
ECHO ^<item type="file"^>
REM Hier musst du schauen, was du von %~a brauchst
ECHO ^<filename^>%~na^</filename^>
ECHO ^<group^>%%i^</group^>
ECHO ^<album^>%%j^</album^>
ECHO ^<title^>%%k^</title^>
ECHO ^<nr^>%%l^</nr^>
ECHO ^<bitrate^>%%m^</bitrate^>
ECHO ^<type^>%n%^</type^>
ECHO ^<bytes^>%~za^</bytes^>
ECHO ^</item^>
))>>"test.xml"
REM +++XML Footer schreiben
(ECHO ^</request^>
)>>"test.xml"
MfG,
Mathe172
[Edit: Das war so klar dass wieder jemand schneller ist...]
Aloha,
zu viel Aufwand
Versuch' es doch so:
Anmerkung: Für die Dateigrößenausgabe muss die Batchdatei imselben Verzeichnis liegen, sonst müsste man den Code etwas anpassen
Ebenso ist bei dir Dateiname nicht definiert, also gehe ich vom eigentlichen, wirklichen, kompletten Dateinamen aus.
Desweiteren gab es bei dir keine Zeile, in der varBitrate genutzt wurde, auch diese habe ich dazugetragen und es fehlt bei dir sowieso ein Prozentzeichen in Zeile 27 ^_^.
Anyway: enabledelayedexpansion ohne Ausrufezeichen ist eh zwecklos aber auch die hätten hier nicht viel genutzt und wie du siehst: Man benötigt es auch gar nicht, da du die for-Variablen direkt nutzen kannst.
greetz André
EDIT AHA! Da wartet man extra, bis der Herr Friemler etwas postet, um sich die Arbeit zu sparen, da loggt er sich aus und ist nicht mehr da, also denkt man: Gut, dann mach' ich das und wenn man postet hat der Herr Friemler sich auch schon ganz weit wieder vorgedrängelt, ja, ja, ja *fg*
P.S.: @mathe, au weia, überfliege noch einmal deine ganzen for-Variablen, das wird nix ^_^ %~a ? %n% ? %~za ?
zu viel Aufwand
Versuch' es doch so:
@echo off & setlocal
REM +++ XML Header schreiben
>test.xml (
ECHO ^<?xml version="1.0" encoding="UTF-8"?^>
ECHO ^<request^>
)
FOR /f "delims=" %%a in ('Dir /b C:\MyMedia\Test\*_*_*_*_*_*.*') do (
FOR /f "delims=_ tokens=1-6" %%i in ('echo %%~a') do (
>>test.xml (
ECHO ^<item type="file"^>
ECHO ^<filename^>%%a^</filename^>
ECHO ^<group^>%%i^</group^>
ECHO ^<album^>%%j^</album^>
ECHO ^<title^>%%k^</title^>
ECHO ^<nr^>%%l^</nr^>
ECHO ^<bitrate^>%%m^</nr^>
ECHO ^<type^>%%n^</type^>
ECHO ^<bytes^>%%~za^</bytes^>
ECHO ^</item^>
)
)
)
REM +++XML Footer schreiben
>>test.xml ECHO ^</request^>
pause
goto :eof
Anmerkung: Für die Dateigrößenausgabe muss die Batchdatei imselben Verzeichnis liegen, sonst müsste man den Code etwas anpassen
Ebenso ist bei dir Dateiname nicht definiert, also gehe ich vom eigentlichen, wirklichen, kompletten Dateinamen aus.
Desweiteren gab es bei dir keine Zeile, in der varBitrate genutzt wurde, auch diese habe ich dazugetragen und es fehlt bei dir sowieso ein Prozentzeichen in Zeile 27 ^_^.
Anyway: enabledelayedexpansion ohne Ausrufezeichen ist eh zwecklos aber auch die hätten hier nicht viel genutzt und wie du siehst: Man benötigt es auch gar nicht, da du die for-Variablen direkt nutzen kannst.
greetz André
EDIT AHA! Da wartet man extra, bis der Herr Friemler etwas postet, um sich die Arbeit zu sparen, da loggt er sich aus und ist nicht mehr da, also denkt man: Gut, dann mach' ich das und wenn man postet hat der Herr Friemler sich auch schon ganz weit wieder vorgedrängelt, ja, ja, ja *fg*
P.S.: @mathe, au weia, überfliege noch einmal deine ganzen for-Variablen, das wird nix ^_^ %~a ? %n% ? %~za ?
@Friemler:
MfG,
Mathe172
Die Ausgabeumleitung bei ECHO-Befehlen sollte man immer vor das ECHO schreiben, das vermeidet Fehlfunktionen des Codes, die tückischerweise nur unter bestimmten Umständen auftreten.
Noch einfacher ist es bei grossen Blöcken, alles auf einmal umzuleiten MfG,
Mathe172
Hallo Mathe,
in dem Fall hier kann man das auch ohne weiteres machen. Wenn der zu schreibende Text aber Klammern enthält (z.B. Inline-VBScript), kommen zu den üblichen Quertreibern
Gruß
Friemler
in dem Fall hier kann man das auch ohne weiteres machen. Wenn der zu schreibende Text aber Klammern enthält (z.B. Inline-VBScript), kommen zu den üblichen Quertreibern
&
, <
und >
, die "escaped" werden müssen, noch die öffnende und schließende Klammer hinzu. Dann wird es meist zu unübersichtlich. Ich bevorzuge es deshalb, die Umleitung vor jede Zeile zu schreiben.Gruß
Friemler
Moin André,
ja, das ist richtig, das kann sogar einen richtigen Geschwindigkeitsboost ergeben. Man muss das eben immer für den Einzelfall abwägen. Codeblöcke, die sehr oft abgearbeitet werden, sollte man wirklich besser mit der Blockwrite-Methode schreiben. Bei Codeblöcken, die nur 1, 2 Mal abgearbeitet werden, sollte man aufgrund der besseren Lesbarkeit darauf verzichten (zumindest wenn der zu schreibende Text Klammern enthält, ich habe das hier halt aus reiner Gewohnheit so gemacht ).
Gruß
Friemler
ja, das ist richtig, das kann sogar einen richtigen Geschwindigkeitsboost ergeben. Man muss das eben immer für den Einzelfall abwägen. Codeblöcke, die sehr oft abgearbeitet werden, sollte man wirklich besser mit der Blockwrite-Methode schreiben. Bei Codeblöcken, die nur 1, 2 Mal abgearbeitet werden, sollte man aufgrund der besseren Lesbarkeit darauf verzichten (zumindest wenn der zu schreibende Text Klammern enthält, ich habe das hier halt aus reiner Gewohnheit so gemacht ).
Gruß
Friemler
Hallo Sodele und willkommen im Forum!
Grüße
bastla
Wenn nach dem Code nichts mehr kommt, wieso muss ich dann eigentlich nach goto :eof?
Musst Du nicht.Ein einfaches EXIT wäre doch sinnvoller, oder übersehe ich da etwas?
In den allermeisten Fällen ist "exit
" ohne "/b
" sinnlos - je nach Aufruf wird die CMD-Shell ohnehin automatisch geschlossen (bzw soll sie das gar nicht werden - Stichwort "Testen").Und sehe ich das richtig, dass ich auf Endlocal verzichten kann?
Soferne es (wie oben) am Ende des Batches steht: ja.Grüße
bastla