Leerer Token am Anfang wird nicht erkannt
Hallo Leute,
leere Token werden ja normalerweise mit der FOR /R Schleife übersprungen.
Mit dem EnableDelayedExpansion sollte das doch aber möglich sein auch den Token am Anfang der Zeile mitzunehmen wenn er leer ist. Klappt aber nicht bei mir.
Hier ist meine Beispieldatei: (test.csv)
A10020;A10020-1-975639001-20040525-ARA-51147;25.05.2004;ARA;1;04NK13730;51147;975639001
;A10020-1-975639001-20041215-ARA-51147;15.12.2004;ARA;1;04NK29630;51147;975639001
;A10020-1-975639001-20040525-A-51147;25.05.2004;A;1;04NK13730;51147;975639001
;A10020-1-975639001-20040525-Z-51147;25.05.2004;Z;1;04NK13730;51147;975639001
Wenn ich nun diesen Batch ausführe:
@echo off & Setlocal EnableDelayedExpansion
for /f "delims=" %%i in (test.csv) do (
set "in=%%i"
for /f "delims=; tokens=1-3" %%a in ("!in:;;=;NULL;!") do (
echo 1[%%a] 2[%%b] 3[%%c] >> output.txt
))
bekomme ich folgenden output: output.txt
1[A10020] 2[A10020-1-975639001-20040525-ARA-51147] 3[25.05.2004]
die restlichen 3 Zeilen werden nicht ausgegeben.
Warum?
Danke!
leere Token werden ja normalerweise mit der FOR /R Schleife übersprungen.
Mit dem EnableDelayedExpansion sollte das doch aber möglich sein auch den Token am Anfang der Zeile mitzunehmen wenn er leer ist. Klappt aber nicht bei mir.
Hier ist meine Beispieldatei: (test.csv)
A10020;A10020-1-975639001-20040525-ARA-51147;25.05.2004;ARA;1;04NK13730;51147;975639001
;A10020-1-975639001-20041215-ARA-51147;15.12.2004;ARA;1;04NK29630;51147;975639001
;A10020-1-975639001-20040525-A-51147;25.05.2004;A;1;04NK13730;51147;975639001
;A10020-1-975639001-20040525-Z-51147;25.05.2004;Z;1;04NK13730;51147;975639001
Wenn ich nun diesen Batch ausführe:
@echo off & Setlocal EnableDelayedExpansion
for /f "delims=" %%i in (test.csv) do (
set "in=%%i"
for /f "delims=; tokens=1-3" %%a in ("!in:;;=;NULL;!") do (
echo 1[%%a] 2[%%b] 3[%%c] >> output.txt
))
bekomme ich folgenden output: output.txt
1[A10020] 2[A10020-1-975639001-20040525-ARA-51147] 3[25.05.2004]
die restlichen 3 Zeilen werden nicht ausgegeben.
Warum?
Danke!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 93321
Url: https://administrator.de/contentid/93321
Ausgedruckt am: 22.11.2024 um 15:11 Uhr
8 Kommentare
Neuester Kommentar
Hallo rübensau!
Ändere die Zeile 2 auf
wobei für "$" gilt, dass damit ein (fast) beliebiges nicht in den Daten vorkommendes Zeichen gemeint ist.
Grüße
bastla
Ändere die Zeile 2 auf
for /f "eol=$ delims=" %%i in (test.csv) do (
Warum?
Meine Interpretation: ";" wird als Defaultwert für einen "Zeilenendekommentar" (siehe "for /?") verwendet - mehr dazu weiß sicher Biber ...Grüße
bastla
Moin Rübensau und bastla,
bastlas Interpretation kann ich nur zustimmen...
Das "eol=§" (o.ä.) in der Zeile 2 ist auf jeden Fall ein notwendiger Schritt.
Dann lasst uns das gleich wasserdicht machen, denn das Drama mit der Redmonder PraktikantInnenlogik geht ja noch weiter.
Zeilen beginnend mit einem ";" werden komplett ignoriert -> Abhilfe "eol=§". Haken dran.
Bleiben zweiProbleme Details zu berücksichtigen:
Also müssen wir dafür sorgen, dass auch, sollte das erste Token NULL sein, auch eine Ausgabe als NULL erfolgt.
Dazu bitte die Zeile
Dritte Schwierigkeit wird (jetzt kommen die Redmonder Praktikanten ins Spiel), dass die Ersetzen-Logik äußerst ausgefeilt ist bei den Brüdern.
Sollte sich die Variable %in% durch ein Ersetzen von Zeichen verlängern, dann werden nicht alle Vorkommnisse des Zu-Ersetzen-Strings gefunden.
Auf Deutsch:
Klasse, oder?
Ein Königreich für einen Baseballschläger...
Anyhow, wenn wir das Ersetzen mehrfach machen, ist auch das Problem erledigt.
Also im Ergebnis:
Die Anzahl der nötigen Zeilen [set "in=!in:;;=;NULL;!" ] lässt sich sicherlich mathematisch berechnen.
Aber nicht von mir...
Bei mehr als 3 NULLABLE Tokens in der Quelldatei würde ich darauf achten.
Grüße
Biber
bastlas Interpretation kann ich nur zustimmen...
Das "eol=§" (o.ä.) in der Zeile 2 ist auf jeden Fall ein notwendiger Schritt.
Dann lasst uns das gleich wasserdicht machen, denn das Drama mit der Redmonder PraktikantInnenlogik geht ja noch weiter.
Zeilen beginnend mit einem ";" werden komplett ignoriert -> Abhilfe "eol=§". Haken dran.
Bleiben zwei
- das zweite Token n einer Zeile, die ";bla;Blubb" heißt, wäre nicht "bla".
>for /f "delims=; tokens=1-3" %i in (";bla;Blubb") do @echo 1[%i] 2[%j] 3[%k]
1[bla] 2[Blubb] 3
Dazu bitte die Zeile
set "in=%%i"
ändern in:set "in=;%%i"
Dritte Schwierigkeit wird (jetzt kommen die Redmonder Praktikanten ins Spiel), dass die Ersetzen-Logik äußerst ausgefeilt ist bei den Brüdern.
Sollte sich die Variable %in% durch ein Ersetzen von Zeichen verlängern, dann werden nicht alle Vorkommnisse des Zu-Ersetzen-Strings gefunden.
Auf Deutsch:
>set "intest=;;;token4;token5;;;"
>echo %intest:;;=;NULL;%
;NULL;;token4;token5;NULL;;
Ein Königreich für einen Baseballschläger...
Anyhow, wenn wir das Ersetzen mehrfach machen, ist auch das Problem erledigt.
Also im Ergebnis:
::---CsvMitNULLWertenRichtigLesen.cmd---------
::@Echo off & setlocal enabledelayedexpansion
for /f "eol= delims=" %%i in (test.csv) do (
set "in=;%%i"
set "in=!in:;;=;NULL;!"
for /f "delims=; tokens=1-3" %%a in ("!in:;;=;NULL;!") do (
echo 1[%%a] 2[%%b] 3[%%c]
))
Die Anzahl der nötigen Zeilen [set "in=!in:;;=;NULL;!" ] lässt sich sicherlich mathematisch berechnen.
Aber nicht von mir...
Bei mehr als 3 NULLABLE Tokens in der Quelldatei würde ich darauf achten.
Grüße
Biber
@Biber
Sollte dann nicht vielleicht auch noch am Ende ein ";" dazu, also
damit die Variable für das letzte Token ebenfalls im Fall des Falles "NULL" und nicht einfach nichts enthält?
Grüße
bastla
Sollte dann nicht vielleicht auch noch am Ende ein ";" dazu, also
set "in=;%%i;"
Grüße
bastla
@bastla
Wir dürfen nur nicht zu offensichtlich unsere Bätche robuster und fehlertoleranter zusammenschroten als gewisse andere Softwareklitschen ihre Betriebssysteme.
Sonst geht es uns wie Mark Russinovich...
Und, um das Erlernte bezüglich rhetorischer Fragen gleich anzuwenden:
Möchtest Du, dass Deine Schnipsel erst nach einem erfolgreich bestandenen Genuine Check das tun dürfen, was sie schon immer taten?
Also formulieren wir es so:
Mit einem weiteren ";" am Ende ist es sicherlich für einen Batchschnipsel schon relativ robust geschrieben.
Grüße
Biber
Sollte dann nicht vielleicht auch noch am Ende ein ";" dazu?
Hast Du den Ausdruck "rhetorische Frage" schon mal gehört? Wir dürfen nur nicht zu offensichtlich unsere Bätche robuster und fehlertoleranter zusammenschroten als gewisse andere Softwareklitschen ihre Betriebssysteme.
Sonst geht es uns wie Mark Russinovich...
Und, um das Erlernte bezüglich rhetorischer Fragen gleich anzuwenden:
Möchtest Du, dass Deine Schnipsel erst nach einem erfolgreich bestandenen Genuine Check das tun dürfen, was sie schon immer taten?
Also formulieren wir es so:
Mit einem weiteren ";" am Ende ist es sicherlich für einen Batchschnipsel schon relativ robust geschrieben.
Grüße
Biber
@Biber
Grüße
bastla
Möchtest Du, dass Deine Schnipsel erst nach einem erfolgreich bestandenen Genuine Check das tun dürfen, was sie schon immer taten?
OK, Du hast mich überzeugt - ich ziehe meine Frage zurück ... Grüße
bastla
Noch ein reumütiger Nachsatz....
Ich wurde eben per PN darauf hingewiesen, dass meine Formulierung
...doch eventuell als abwertend oder diskriminierend aufgefasst werden könnte.
Sehe ich ein und entschuldige mich dafür.
Natürlich hätte es heißen müssen:
Dritte Schwierigkeit wird (jetzt kommen die Redmonder PraktikantInnen ins Spiel), dass die Ersetzen-Logik äußerst ausgefeilt ist bei den Brüdern und Schwestern.
Grüße
Biber
Ich wurde eben per PN darauf hingewiesen, dass meine Formulierung
Dritte Schwierigkeit wird (jetzt kommen die Redmonder Praktikanten ins Spiel), dass die Ersetzen-Logik äußerst ausgefeilt ist bei den Brüdern.
...doch eventuell als abwertend oder diskriminierend aufgefasst werden könnte.
Sehe ich ein und entschuldige mich dafür.
Natürlich hätte es heißen müssen:
Dritte Schwierigkeit wird (jetzt kommen die Redmonder PraktikantInnen ins Spiel), dass die Ersetzen-Logik äußerst ausgefeilt ist bei den Brüdern und Schwestern.
Grüße
Biber
*ROFL*