schoco
Goto Top

Exportdatei mit fester Satzlänge in CSV-Datei konvertieren

Leider muß ich um Hilfe bitten, ohne selbst bis jetzt zu Lösungen beigetragen zu haben.
Ich bin, was Batchprogrammierung anbelangt, reichlich unbeleckt. Aber das kann sich ja
noch ändern.

Ich bekomme wöchentlich eine Textdatei, bei der die Spaltentrennzeichen an einer fixen Stelle stehen, so dass ein Datensatz mit immer gleicher Satzlänge entsteht. Das hat aber auch zur Folge, dass in den einzelnen Spalten Leerstellen zwischen dem letzten Zeichen der Spalte und dem Spaltentrennzeichen entstehen.
Jetzt sollen diese Sätze der Textdatei so abgeändert werden, dass das Spaltentrennzeichen direkt nach dem letzten Zeichen der Spalte
steht. Es kann aber auch sein, dass eine Spalte leer ist. Dann müssten außer den Leerstellen auch ein Spaltentrennzeichen wegfallen.
Der ganze Datensatz besteht aus 9 Spalten.
Jetzt hoffe ich, dass mir jemand helfen kann und bedanke mich schon im Voraus.
Kommentar vom Moderator Biber am Sep 19, 2009 um 14:24:02 Uhr
Den Titel hab ich geändert von "Aus Textdatei Leerstellen entfernen" auf "Exportdatei mit fester Satzlänge in CSV-Datei konvertieren".
Auch wenn es nicht comma separated ist, sondern andere Delimiter hat.

Content-Key: 125199

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

Printed on: April 19, 2024 at 10:04 o'clock

Member: Biber
Biber Sep 17, 2009 at 15:28:29 (UTC)
Goto Top
Moin Schoco,

ist mir (und vermutlich auch ein paar anderen) eine Spur zu abstrakt.
Kannst Du mal bitte ein paar Zeilen dieser Textdatei (5 Zeilen IST; 5 Zeilen SOLL) veröffentlichen?

Falls es irgendwelche schützenswerten Daten sein sollten (Schweizer Kontoverbindungen deines F.D.P.-Landesverbandes oder sowas), dann ggf. anonymisieren.

Danke
Biber
Member: Schoco
Schoco Sep 18, 2009 at 10:01:17 (UTC)
Goto Top
Hallo Biber,
in dem Beispiel habe ich den Nachnamen durch X, die Strasse durch Y und den Ort durch Z ersetzt. Immer bei den 10 Einsen ist der Anfang. Der ganze Satz ist immer incl. Satzendezeichen 315 Stellen lang. jetzt sollte das erste Spaltentrennzeicjen ( Semi -kolon) nach der zehnten eins, das Zweite nach Günter, das Dritte nach dem letzten X kommen, usw. Es gibt auch Leere Spalten, wie nach den Architekten im 3. Satz. Die müssten dann ganz wegfallen.
Jetzt wollte ich das erste Mal FDP wählen, aber wenn die Konten in der Schweiz haben, muss ich das noch überdenken.

Gruss

Schoco

1111111111 Günter XXXXXX YYYYYYYYYY 7 21111 ZZZZZZZZZZZZ
1111111111 Dr.med. Ulrich XXXXXXXX YYYYYYYY Str. 21 61111 ZZZZZZZZZZZZ
1111111111 Architekten XXX YYYYYYYYYY 12 21111 ZZZZZZZZ
Member: Biber
Biber Sep 18, 2009 at 11:19:33 (UTC)
Goto Top
Moin Schoko,

kann ich mit leben, wenn du nicht auch noch die F.D.P. wählst. Die haben schon fast mehr 14% Stimmenanteil als sie verdienen. face-wink

Zu Deiner Fix-Len-Datei:
Ich verstehe das so richtig, das im Moment die Datei (skizziert) so aussieht:
0         1         2         3         4         5         6         7....
01234567890123456789012345678901234567890123456789012345678901234567890123456
1111111111 Günter              XXXXXX     YYYYYYYYYY 7     21111 ZZZZZZZZZZZZ 
1111111111 Dr.med. Ulrich      XXXXXXXX   YYYYYYYY Str. 21 61111 ZZZZZZZZZZZZ 
1111111111 Architekten         XXX        YYYYYYYYYY 12    21111 ZZZZZZZZ
d.h. das spätere "Feld" Name ist z.b von Position.0 beginnend 10 Stellen lang,
Feld "Vorname" von Pos. 11 an 20 Stellen lang etc?
Und zusätzliche führende/abschliessende Hochkomma brauchen nicht rein bei den Textfeldern, sondern nur je ein Semikolon?

Grüße
Biber
Member: Schoco
Schoco Sep 18, 2009 at 11:49:25 (UTC)
Goto Top
Hallo Biber,

jetzt wollen die Experten auch noch ein anderes Feldtrennzeichen. Es muss nachher so aussehen wie auf dieser Datei. Da sind zwar die Namen weggelassen, aber man kann doch erkennen was gewollt ist. Ich weiß gar nicht, was der senkrechte Strich für ein Zeichen ist.

Gruß
Schoco


111111111|YYYYYYYYY Str.|2|84000|ZZZZZZZZZ
111111112|YYYYYstr.|30d|17000|ZZZZZZZZ
Member: Biber
Biber Sep 18, 2009 at 12:32:37 (UTC)
Goto Top
Moin Schoco,

in diesem abgelegenen Seitenarm des Forums gelten zwar nur ganz wenige Regeln.
Aber für die Einhaltung dieser ganz paar Regeln haben die hier einen als äußerst sturköpfigen Halbtagsmoderator angeheuert, soweit ich weiß.

Bevor der hier antrabt und den Beitrag kompostiert, rufe ich noch mal ins Gedächtnis:

Regel 1: Eine Frage ist verständlich und mit allen für eine villständige Problembeschreibung zu stellen. Im Idealfall.
Regel 2. Da der Normalfall wesentlich häufiger eintritt als der Idealfall und vor dem Vorschlagen einer Lösungsskizze Rückfragen gestellt werden, sollten erst diese in der Reihenfolge ihres zeitlichen Eintreffens beantwortet werden.

Danach sagt dann in der Regel der hilfswillige Gutmensch "JETZT glaube ich verstanden zu haben, was du willst und ein Lösungsansatz wäre....Bla..".

Bitte schau dir noch meine Kommentare an und insbesondere diejenigen, die am äußersten rechten Rand mit einem Fragezeichen abrupt enden.

Wenn du bitte kurz diese beantwortest, dann sage ich dir auch, was das Pipesymbol für ein Zeichen ist.

Danke
Biber
Member: Schoco
Schoco Sep 18, 2009 at 13:46:25 (UTC)
Goto Top
Hallo Biber,
entschuldige, ich stand wohl etwas auf der Leitung.
Du hast richtig verstanden. Durch das Kopieren der Beispieldatei hat sich die Ansicht etwas verschoben. Von 0 beginnend 10 Stellen lang ist eine Nummer, Vorname immer von von Pos. 39 an 32 Stellen, Nachname immer von Pos. 71 an 32 Stellen. usw.
zusätzliche führende/abschliessende Hochkomma brauchen nicht rein nur, wie im 2. Beispiel der senkrechte Strich.
Ich bin noch recht neu hier, deshalb das etwas ungeschickte hantieren. Aber die Regeln werde ich auch noch intus kriegen.

Grüsse
Schoco
Member: Biber
Biber Sep 18, 2009 at 15:19:37 (UTC)
Goto Top
Moin Schoco,

JETZT glaube ich verstanden zu haben, was Du willst und ein Lösungsansatz wäre:

@echo off & setlocal
goto skipdoku
0         1         2         3         4         5         6         7         8
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
<---nr --><------ignore---------------><------ vorname ---------------><--name -><<--Whatever>
1111111111                             Günter                          XXXXXX    YYYYYYYYYY    7 
1111111111                             Dr.med. Ulrich                  XXXXXXXX  YYYYYYYY Str. 21
1111111111                             Architekten                     XXX       YYYYYYYYYY    12


:skipdoku

FOR /F "delims=" %%i in (e:\schnipsel\schoco.txt) do set "line=%%i" & call:processline  
Goto :eof

:processline
set       "var=nr" & call:trim   %line:~0,10%  
set  "var=vorname" & Call:Trim  %line:~39,32%  
set     "var=name" & Call:Trim  %line:~71,10%  
set "var=whatever" & call:trim  %line:~81,12%  

Echo %nr%^|%vorname%^|%name%^|%whatever%^| usw....
:goto :eof

:trim ---setzt eine Variable %var1% auf Wert (alle Parameter)
Set "%var%=%*"  
goto :eof

Ergebnis wäre
>e:\schnipsel\schoco
1111111111|Günter|XXXXXX|YYYYYYYYYY| usw....
1111111111|Dr.med. Ulrich|XXXXXXXX|YYYYYYYY| usw....
1111111111|Architekten|XXX|YYYYYYYYY| usw....

Ich hoffe, der Ansatz ist nachvollziehbar.

Grüße
Biber
Member: Schoco
Schoco Sep 18, 2009 at 19:25:53 (UTC)
Goto Top
Hallo Biber,
das Ergebnis wäre genau das was ich brauche. Aber alles kann ich nicht ganz nachvollziehen. Kannst Du mir bitte ein paar erklärende Worte schreiben. Ich hab ja sogar noch meine Probleme mit dem senkrechten Strich zwischen den Spalten. Hoffentlich erwarte ich nicht zuviel von Dir.
Noch einen schönen Abend.

Grüsse

Schoco
Member: Biber
Biber Sep 18, 2009 at 21:36:50 (UTC)
Goto Top
Moin Schoco,

ein paar erklärende Worte versuch ich mal, aber im Erklären bin ich nicht so gut.

Vorab - zum Testen solltest Du auch Deine Batchdatei von CMD-Prompt aus starten (und nicht etwa über einen Link auf dem Desktop o.ä.).
Und wenn Du schon mal am CMD-Prompt bist, kannst Du jederzeit Hilfe zu allen CMD-Befehlen anzeigen lassen mit FOR/?, SET/?, Goto/? etc.

Nun denn...
FOR /F "delims=" %%i in (e:\schnipsel\schoco.txt) do set "line=%%i" & call:processline
Goto :eof
diese erte FOR/F liest die Input-Datei (bei mir die "e:\schnipsel\schoco.txt") jeweils zeilenweise ein... also bei Dir in der Länge 351 oder so.
Diese ganze Zeile wird als Variable %line% zwischengespeichert und weiter unten zerbröselt.
Das Zerbröseln wird mit dem Call-Block ":processline" für jede Zeile aufgerufen.
Nach allen Zeile ist die Verarbeitung logischerweise beendet und ich lasse sage genau das dem Batch durch die Folgezeile "goto :eof".
Ist die neudeutsche Redmonder Klausel für "Habe fertig.".


Die Vearbeitung in dem ":processline"-Block ist stumpfsinnig, aber wartbar und nachvollziehbar.

:processline
set "var=nr" & call:trim %line:~0,10%
set "var=vorname" & Call:Trim %line:~39,32%
set "var=name" & Call:Trim %line:~71,10%
set "var=whatever" & call:trim %line:~81,12%

Echo %nr%^|%vorname%^|%name%^|%whatever%^| usw....
:goto :eof

Jedes "Feld", das ich aus dem "Datensatz" lesen will ist ja ein Substring aus der ganzen Zeile.
Die von mir mangels insiderwissen als "nr" benannte Variable beginnt mit dem ersten Zeichen der Zeile (in CMD-Syntax Position 0) und hat die Länge 10.
Batch-Syntax: %line:~0,10% --> Teilstring von %line% von Pos 0 in Länge 10.
Für %vorname%, %name% usw. entsprechend.
Siehe mein kunstvoll gemaltes Lineal im Schnipsel.

An Ende des CALL-Blocks wird das Ganze (alle Variablen) aneinandergereiht als wieder eine Zeile, getrennt durch dieses Pipesymbol "|".
Dieses hat im Batch spezielle Bedeutung, deshab muss es beim ECHO-Befehl "maskiert" werden mit einm Caret ("^"). Is' so.
Ich muss also ein "^|" schreiben um ein "|" zu erzeugen.
Genauso wie ich immer 10 Zeilen Text brauche um eine Zeile Code zu erklären...

Was vergessen?
Ach ja.

Du wolltest den Text ohne trailing blanks haben, deshalb hab ich noch eine Pseudo-Funktion Trim() eingebaut.
Im Batch natürlich keine Funktion Trim(), sondern einen CALL-Block namens :Trim.

Nimm den einfach erstmal so hin... der ist ja nicht weiter wesentlich, solange er das tut, was er vorgibt zu können.

:trim ---setzt eine Variable %var1% auf Wert (alle Parameter)> Set "%var%=%*"
goto :eof

Auch dieser CALL-Block wird wieder mit "goto :eof" abgeschlossen, wobei die "Habe fertig"s der Call-Blöcke bedeuten ":Fertig, zurück nach dort, von wo der Call aufgerufen wurde".

Hoffe es hilft zum Einstieg.

Grüße
Biber
Member: Schoco
Schoco Sep 24, 2009 at 12:57:05 (UTC)
Goto Top
Hallo Biber,
danke, dass Du noch mitten in der Nacht Deine letzten Erklärungen verfasst hast. Ich antworte erst heute, weil ich ein paar Tage in den Bergen war.
Heute habe ich versucht, das umzusetzen, was Du mir geschrieben hast. Ich glaubte, es soweit begriffen zu haben, aber wenn ich die Batch laufen lasse, erzeugt sie mir zwar das pipesymbol, aber die Leerstellen bleiben.
Kann das daran liegen, dass manche Felder wie Titel oder co nicht immer belegt sind? Ich kopiere Dir mal das was ich was ich aus Deinem Ansatz produziert habe. Du siehst sicher schnell, wo es noch hapert.

Viele Grüsse

Schoco
@echo off & setlocal
goto skipdoku
0         1         2         3         4         5         6         7         8
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
<---nr --><------ignore---------------><------ vorname ---------------><--name -><<--Whatever>
1111111111                             Günter                          XXXXXX    YYYYYYYYYY    7
1111111111                             Dr.med. Ulrich                  XXXXXXXX  YYYYYYYY Str. 21
1111111111                             Architekten                     XXX       YYYYYYYYYY    12


:skipdoku

FOR /F "delims=" %%i in (d:\adressen\ret.txt) do set "line=%%i" & call:processline  
Goto :eof

:processline
set       "var=nr" & call:trim   %line:~0,10%  
set    "var=titel" & call:trim   %line:~21,17%  
set  "var=vorname" & call:trim   %line:~38,32%  
set     "var=name" & call:trim   %line:~70,32%  
set       "var=co" & call:trim   %line:~102,32%  
set  "var=strasse" & call:trim   %line:~134,22%  
set       "var=hn" & call:trim   %line:~156,8%  
set      "var=plz" & call:trim   %line:~164,5%  
set      "var=ort" & call:trim   %line:~170,19%  
Echo %nr%^|%titel%^|%vorname%^|%name%^|%co%^|%strasse%^|%hn%^|%plz%^|%ort%^|
:trim ---setzt eine Variable %var1% auf Wert (alle Parameter)
Set "%var%=%*"  
goto :eof
Member: Biber
Biber Sep 24, 2009 at 17:53:54 (UTC)
Goto Top
Moin Schoco,

sorry, ich war woanders unterwegs.

Ich seh auch mit bloßem Auge keine Fehler.
Andererseits....
Fehler in der eigenen (Programmier-) Logik will ja auch niemand sehen.

Nein, lass es uns so machen:
Schick mir bitte eine (ggf. anonymisierte) 5-Zeilen-Datei mit 5 Deiner d:\adressen\ret.txt zum Spielen und Testen.
Möglichst Zeilen, in denen dieser Fehler auftritt mit den nicht unterdrückten Leerzeichen.
Meine Mail-Adresse findest Du in meinem Benutzerprofil.

Grüße
Biber
Member: Schoco
Schoco Sep 29, 2009 at 06:13:06 (UTC)
Goto Top
Hallo Biber,
es funktioniert alles soweit wunderbar, nur wenn das Zeichen & in den zu bearbeitenden
Sätzen vorkommt, wird das als unbekannter Befehl aufgefasst. Ab dem "&" wird der Rest der Spalte weggelassen.
Hoffentlich hast Du den Wahlausgang gut überlebt.

Grüsse

Schoco
Member: Biber
Biber Sep 29, 2009 at 20:13:11 (UTC)
Goto Top
Moin Schoko,
Zitat von @Schoco:
Hallo Biber,
...
> Hoffentlich hast Du den Wahlausgang gut überlebt.
Klar, ich habe ja auch im Vorfeld immer für Tigerenten- und Biene-Maja-Koalitionen geworben.
Und niemals frauenfeindliche Witze über die Cheffinnen von CDU oder F.D.P. gemacht.

Zu Deiner Frage:
es funktioniert alles soweit wunderbar, nur wenn ....
Diese Art der Formulierungen gibt es außer bei Programmierern nur noch im Marketing.
In der IT kennst/kannst Du es ja offensichtlich schon.
In der Werbung musst du mal drauf achten - da nennt es sich "der eingeschränkte Superlativ"
Beispiele
  • "Die wahrscheinlich längste Praline der Welt</i>"
  • "die vielleicht schönste Zusammenstellung von Love-Songs.."
  • "der "vermutlich" beste Film von Regisseur XY"

> das Zeichen & in den zu bearbeitenden Sätzen vorkommt,
wird das als unbekannter Befehl aufgefasst. Ab dem "&" wird der Rest der Spalte weggelassen.
Jepp, das "&"-zeichen hat Sonderbeutung im Batch.
Und muss da "maskiert" (siehe Forumssuche) werden.
Da da nicht so einfach geht in deinem Fall (durch Maskierung würde noch ein "^"-Zeichen vor das "&" gestellt werden und wir würden die feste Satzlänge ändern, deshalb müssen wir wohl das Zeichen "&" temporär durch ein anderes Ersetzen (nur im Batch) und hinterher wieder Rückersetzen.

Gibt es denn ein "normales" Tastaturzeichen, dass NIE vorkommt in den ganzen zeichenketten, z.B. das Paragraphzeichen ("§") oder so etwas?
Dann bauen wir das morgen ein.

Grüße
Biber
Member: Schoco
Schoco Sep 29, 2009 at 22:12:59 (UTC)
Goto Top
Hallo Biber,
ich komme gerade von einer kleinen Geburtstagsfeier. Da will ich Dir so spät nur noch bestätigen,
dass das Paragraphzeichen § für diesen Zweck verwendet werden kann.

Gute Nacht

Schoco
Member: Biber
Biber Oct 02, 2009 at 07:12:51 (UTC)
Goto Top
Moin Schoco,

sorry, hatte die letzten Tage etwas wenig Zeit .

Zu dieser &-Maskierungsfrage:
In Anlehnung an meine oben gepostete Beispielskizze und die dort verwendeten Testdaten wäre ein Ansatz so:
@echo off & setlocal
goto skipdoku
0         1         2         3         4         5         6         7         8
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
<---nr --><------ignore---------------><------ vorname ---------------><--name -><<--Whatever>
1111111111                             G³nter                          XXXXXX    YYYYYYYYYY    7 
1111111111                             Dr.med. Ulrich                  XXXXXXXX  YYYYYYYY Str. 21
1111111111                             Architekten                               YYYYYYYYYY    12
1111111111                             Dr.med. Ulrich                  XXXXXXXX  YYYYYYYY Str. 21


:skipdoku

FOR /F "delims=" %%i in (e:\schnipsel\schoco.txt) do set "line=%%i" & call:processline  
Goto :eof

:processline
Set "Line=%line:&=§%"  
set       "var=nr" & call:trim   %line:~0,10%  
set  "var=vorname" & Call:Trim  %line:~39,32%  
set     "var=name" & Call:Trim  %line:~71,10%  
set "var=whatever" & call:trim  %line:~81,12%  
Set "lineout=%nr%^|%vorname%^|%name%^|%whatever%^| usw...."  
Set "lineOut=%lineout:§=^&%"  
Echo %lineOut%
REM Echo %nr%^|%vorname%^|%name%^|%whatever%^| usw....
:goto :eof

:trim ---setzt eine Variable (Parameter1) auf Wert (Parameter Rest)
Set "%var%=%*"  
goto :eof

Output wäre (bei Testdaten , in denen "Günter & Erika" bzw. "Architekten & Co" enthalten sind):
>schoco
1111111111|Günter & Erika|XXX|XXX    YYYYY| usw....
1111111111|Dr.med. Ulrich|XXXXXXXX|YYYYYYYY| usw....
1111111111|Architekten & Co||YYYYYYYY| usw....

Die verwendete Ersetzungssyntax, die sicherlich etwas kryptisch aussieht, wird erklärt am CMD-Prompt unter CMD /? oder Set /? oder in diversen Beiträgen hier im Bereich "Batch & Shell".

Grüße
Biber
Member: Biber
Biber Oct 05, 2009 at 13:02:00 (UTC)
Goto Top
Moin Schoco,

sind noch Fragen offen oder können wir einen Haken in der Farbe eines mittelalten Gyros Pita an den Beitrag pappen?

Grüße
Biber
Member: Schoco
Schoco Oct 06, 2009 at 12:59:44 (UTC)
Goto Top
Hallo Biber,

soweit ich selbst das überblicke, ist alles bestens. Ich will nur noch den Test der "Experten" abwarten, man weiß ja nie. Vielleicht dauert es noch ein, zwei Tage. Ich melde mich sofort und hoffe dass die Farbe noch stimmt bis dahin.

Grüsse

Schoco
Member: Schoco
Schoco Oct 15, 2009 at 13:04:37 (UTC)
Goto Top
Hallo Biber,

der Beitrag kann jetzt als gelöst markiert werden. Bei Dir möchte ich mich herzlich für die Hilfe bedanken und kann nur noch hoffen, dass Du Dich langsam an die vielen Prozente Deiner Lieblingspartei FDP gewöhnst.

Grüsse

Schoco