rangald
Goto Top

String wird nicht in die zweite Text datei kopiert

Hallo zusammen,
es geht um folgende, ich möchte eine vcf-List Datei in einzelne vcfDateien splitten.
Dafür habe ich mir auch schon ein Bacth Skript zusammen gebastelt, welches auch soweit funktioniert, allerdings habe ich nun das Problem, das das Skript scheinbar immer dann abbricht, wenn in dem ausgelesen String ein ';' vorkommt.

Zur weiteren Info: lmod ist ein Tool, welches nichts anderes macht, als eine Zeile x (Parameter: /L) anstatt auf dem Bildschirm auszugeben in eine Datei umleitet

Aber hier erstmal das Skript:

SET "end="
SET "counter=1"
SET "filecount=1"
SET "global=0"

:begin
IF %global% == %2 GOTO :clean
TYPE %1 | lmod /E /L%counter% > tmp.dat
FOR /F %%i in (tmp.dat) do set "end=%%i"
more tmp.dat >> %filecount%.vcf
IF %end% == END:VCARD GOTO :newfile
SET /a counter=counter+1
GOTO :begin


:newfile
SET /a counter=counter+2
SET /a filecount=filecount+1
SET /a global=global+1
GOTO :begin

:clean
del tmp.dat

So das problem stellt sich nun so dar, das er scheinbar immer dann abbricht, wenn er die Zeile 'more tmp.dat >> %filecount%.vcf' abarbeitet und sich in der tmp.dat ein String befindet, in dem ein Semikolon vorkommt.

Nun noch der Vollständigkeit halber ein Beispiel, wie ein vcf Datensatz aussieht:

BEGIN:VCARD
VERSION:2.1
N:Mustermann;Hans
FN:Hans Mustermann
ORG:Muster GmbH
ADR;WORK:;;Mustergasse 11;Musterstadt;Bundesland;88888;Deutschland
BDAY:19871031
TEL;HOME:+49 8888888888
EMAIL:h.Mustermann@gmx.de
TEL;CELL:+49 0160888888888
END:VCARD

Ich hoffe ihr könnt mir da ein bsichen helfen.

P.S. das ist mein erstes batch Skript, ich bin also für Verbesserungsvorschläge offen.

Gruß,
Rangald

Content-Key: 57268

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

Printed on: April 18, 2024 at 12:04 o'clock

Member: Biber
Biber Apr 22, 2007 at 15:46:03 (UTC)
Goto Top
Moin Rangald,

willkommen im Forum.

Ich denke, Du bist bei der Vermutung nach der "Fehler"-Ursache auf der falschen Fährte.
Ich denke, es sind zwei andere Fehlerursachen, die eher handwerklicher Natur sind (keine Dankfehler).

1) Falls in einer Zeile Leerzeichen enthalten sind, würde davor auch das erste Token der FOR /F-Anweisung (%%i) enden.
Beispiel am CMD-Prompt:
$cmd$type vcard.txt
BEGIN:VCARD
VERSION:2.1
N:Mustermann;Hans
FN:Hans Mustermann
ORG:Muster GmbH
ADR;WORK:;;Mustergasse 11;Musterstadt;Bundesland;88888;Deutschland
BDAY:19871031
TEL;HOME:+49 8888888888
EMAIL:h.Mustermann@gmx.de
TEL;CELL:+49 0160888888888
END:VCARD
Z:\>
$cmd$FOR /F %i in (vcard.txt) do @echo "%i"  
"BEGIN:VCARD"  
"VERSION:2.1"  
"N:Mustermann;Hans"  
"FN:Hans"  
"ORG:Muster"  
<b>"ADR;WORK:;;Mustergasse"</b>  
"BDAY:19871031"  
"TEL;HOME:+49"  
"EMAIL:h.Mustermann@gmx.de"  
"TEL;CELL:+49"  
"END:VCARD"  

Z:\>
$cmd$FOR /F <b>"delims="</b> %i in (vcard.txt) do @echo "%i"  
"BEGIN:VCARD"  
"VERSION:2.1"  
"N:Mustermann;Hans"  
"FN:Hans Mustermann"  
"ORG:Muster GmbH"  
"ADR;WORK:;;Mustergasse 11;Musterstadt;Bundesland;88888;Deutschland"  
"BDAY:19871031"  
"TEL;HOME:+49 8888888888"  
"EMAIL:h.Mustermann@gmx.de"  
"TEL;CELL:+49 0160888888888"  
"END:VCARD"  

Ich denke, Du siehst den Unterschied - Du solltest "delims=" als Klausel einbauen in Deine FOR/F-Anweisung.

2) Bei der IF-Prüfung der Variablen solltest Du diese Syntax verwenden:
REM :::::: Wackelige Prüfung: IF %end% == END:VCARD
IF [%end%] == [END:VCARD] goto....
::- oder besser -
IF "%end%" == "END:VCARD" goto ...  

Das verhindert einen Syntaxfehler, falls mal die Variable %end% leer ist oder aus mehreren "Worten" besteht.

Probier es mal mit diesen beiden Änderungen bitte und poste das Ergebnis.

Gruss
Biber
Member: miniversum
miniversum Apr 22, 2007 at 16:02:57 (UTC)
Goto Top
Ui jetzt wollte ich eigentlich meinen Vorschlag posten. Oder soll ichmal lieber noch etwas warten wegen Lerneffekt und so?

miniversum
Member: Rangald
Rangald Apr 22, 2007 at 17:57:00 (UTC)
Goto Top
@Biber
als erstes mal vielen Dank für die Hilfe.

Das hat hervorragend funktioniert, ich habe gar nicht daran gedacht, das es an dem Leerzeichen, in der nächsten Zeile, liegen könnte.
Zum Verständnis für mich, was bedeutet denn die Option 'delims=', ich habe das schon in einigen Beispielen gesehen, habe aber noch nicht gefunden, was es bewirkt ?

Bzgl. der Prüfung, ebenfalls nochmals Dank dafür, soweit war ich noch gar nicht, das wäre wahrscheinlich aufgekommen, wenn der erste Durchlauf stattgefunden hätte.

Wie gesagt, es ist mein erstes Skript und das ist mit Grundkenntnissen eher durch "Learning by doing" entstanden.

So, eine Frage hätte ich noch, ich hoffe das ist ok, wenn ich das ebenfalls unter diesem Thread schreibe.

Ist es möglich, das ich in einer Textdatei spezielle Strings Abfrage und zählen lasse ?
Also bisher ist es so, das ich als zweites Befehlskommando, bei Aufruf der .bat Datei, die Anzahl der zu Bearbeitenden Datensätze angeben muß, da die .bat Datei sonst in einer Endlosschleife endet.
Eleganter wäre natürlich, das ich die vcf-list Datei auslese und beispielsweise alle Zeilen in denen "BEGIN:VCARD" steht zählen lasse und diese Zahl dann an eine Variable übergebe.

Ich weiß das das eigentlich nicht notwendig ist und ich habe auch schon versucht das mit einem find zu erreichen, das Problem, welches ich jedoch habe, ist das zählen.


Vielen Dank nochmal

Gruß,
Rangald
Member: miniversum
miniversum Apr 22, 2007 at 18:19:47 (UTC)
Goto Top
Versuchs mal so:
for /F "delims=:" %%a in ('findstr /N "suchstring" Datei.txt') do set nummer=%%a

In %nummer% steht dann die Zahl wie viele Zeilen den suchstring enthalten.

miniversum
Member: miniversum
miniversum Apr 22, 2007 at 19:36:14 (UTC)
Goto Top
Ups ich merk grade..
Meintest du die Anzahl Dateien in dem Verzeichnis mit der Anzahl Datensätze?

miniversum
Member: Rangald
Rangald Apr 22, 2007 at 21:02:52 (UTC)
Goto Top
@miniversum

erstmal danke für die schnelle Info.

Nein es geht schon um die Anzahl der Datensätze innerhalb einer Datei, die gezählt werden sollen.
Ich kann es im Moment nicht testen, aber das ist schon mal ein neuer Ansatz an den ich mich begeben kann.

Gruß,
Rangald
Member: Biber
Biber Apr 23, 2007 at 08:57:16 (UTC)
Goto Top
Moin Rangald,

noch ein Verweis zu einer Antwort auf Deine Frage Was bedeutet/bewirkt "delims="?...

Aus der Hilfe zur FOR-Anweisung ("FOR /?" am CMD-Prompt);
For /?
skip=n - Gibt die Anzahl der Zeilen an, die am Anfang einer
Datei übersprungen werden.
delims=xxx - Gibt einen Satz von Trennzeichen an. Diese ersetzen
die Standardtrennzeichen TAB und Leerzeichen.
tokens=x,y,m-n - Gibt an, welche Token von jeder Zeile an die
FOR-Schleife weitergegeben werden.

Gruss
Biber
Member: miniversum
miniversum Apr 23, 2007 at 08:57:47 (UTC)
Goto Top
Oh hab grade gemerkt das es ja garncith stimmt. müste so gehen:
set nummer=0
for /F "delims=:" %%a in ('findstr /N "suchstring" Datei.txt') do set /a nummer+=1

miniversum
Member: bastla
bastla Apr 23, 2007 at 09:42:32 (UTC)
Goto Top
... wobei sich dann auch die Nummerierung / Zerlegung erübrigt und folgendes genügt:
set nummer=0
for /F %%a in ('findstr "suchstring" Datei.txt') do set /a nummer+=1  

Grüße
bastla
Member: Biber
Biber Apr 23, 2007 at 10:57:54 (UTC)
Goto Top
...wobei sich auch dieses noch einfacher lösen ließe...
for /f "delims=: tokens=3" %%i in ('find /i /c "suchstring" "x:\pfad\Datei.txt"') do set anzahl=%%i  

Find.exe hat noch (im Gegensatz zu FindStr.exe) den manchmal nützlichen Schalter /C wie /Count.

Gruss
Biber
Member: bastla
bastla Apr 23, 2007 at 17:19:03 (UTC)
Goto Top
... wozu noch der Hinweis anzubringen wäre, dass die Nummer des Tokens (im Beispiel: 3) davon abhängt, ob im verwendeten Pfad der zu durchsuchenden Datei ein ":" vorkommt (also mit Laufwerksangabe) - ansonsten ist "tokens=2" zu verwenden.

Grüße
bastla
Member: Biber
Biber Apr 23, 2007 at 18:09:44 (UTC)
Goto Top
...wobei ich ungern darauf verzichte, das letzte Wort zu haben...

Wenn es nun tatsächlich unkalkulierbar oder von zufälligen Konstellationen abhängig sein sollte, ob nun der zurückgegebene String ein oder zwei Leerzeichen enthält,
weil mal eine Datei in der Form xx.txt und mal in der Form x:\pfad\xx.txt übergeben wird, dann:
for /f "delims=: tokens=1,*" %%i in ('find /i /c "suchstring" dateiname.txt') do @for %%j in (%%j) do @set /a anzahl=%%j  

[Wobei bastla natürlich recht hat: bei der Datei tmp.dat oben im Beispiel müsste "Tokens=2" gesetzt werden.
Ebenso bei allen Dateien ohne explizite Laufwerksangabe und allen UNC-Pfadangaben wie "\\meinsörva\schehr" etc.]

Gruss Biber