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.
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.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Kommentar vom Moderator Biber am 19.09.2009 um 16: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.
Auch wenn es nicht comma separated ist, sondern andere Delimiter hat.
Content-ID: 125199
Url: https://administrator.de/contentid/125199
Ausgedruckt am: 17.11.2024 um 02:11 Uhr
18 Kommentare
Neuester Kommentar
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
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
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.
Zu Deiner Fix-Len-Datei:
Ich verstehe das so richtig, das im Moment die Datei (skizziert) so aussieht:
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
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.
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
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
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
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
Moin Schoco,
JETZT glaube ich verstanden zu haben, was Du willst und ein Lösungsansatz wäre:
Ergebnis wäre
Ich hoffe, der Ansatz ist nachvollziehbar.
Grüße
Biber
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
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...
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.
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
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.Goto :eof
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
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
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
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
Moin Schoko,
...
> 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:
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
> das Zeichen & in den zu bearbeitenden Sätzen vorkommt,
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
...
> 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
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:
Output wäre (bei Testdaten , in denen "Günter & Erika" bzw. "Architekten & Co" enthalten sind):
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
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