ipzipzap
Goto Top

Textdatei mit festen Spaltenbreiten per Batch nach CSV konvertieren?

Hallo,

ich habe eine Textdatei, die wie folgt aussieht:

...
05/07/2011 14:46 Admin                    ->#Printed                              A2 - Musterfirma 2                           Mustermann, Sabine                           00-0000-00-0000000000000000
05/07/2011 14:46 Admin                    ->#Printed                              A1 - Musterfirma Musterfirma Musterfirma MustMustermann, Max                              00-0000-00-0000000000000000
05/07/2011 14:46 Admin                    ->#Printed                              B1 - Musterfirma 3                           Mustermann, Maria                            00-0000-00-0000000000000000
...

Nun brauche ich das als CSV, damit ich die Datei direkt in Excel öffnen kann. Da es feste Spaltenbreiten sind, sollte das ja nicht sooo schwer sein, nur wie? ^^
Mit findstr und dem "delims" Parameter bin ich nicht so wirklich weitergekommen, da ich kein Leerzeichen als Trenner verwenden kann.

Das "Admin" und "->#Printed" brauche ich nicht, aber alle anderen Spalten:

Datum;Uhrzeit;Firma;Name;Nummer

Danke im Voraus
Dino


PS:
Die Option, die Datei in Excel zu öffnen und dann per "Text in Spalten" zu formatieren, scheidet aus, weil die Datei mehrmals die Stunde aktualisiert wird und ich das Ganze halt automatisieren möchte. Außerdem kann man sie als CSV direkt auch in anderen Programmen verwenden.

Content-ID: 165836

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

Ausgedruckt am: 21.11.2024 um 12:11 Uhr

Biber
Biber 07.05.2011 um 16:17:29 Uhr
Goto Top
Moin ipzipzap,

natürlich kannst du jeweils die ganze Zeile mit ihren 200 Zeichen einlesen, jeweils mit der batch-eigenen Substringfunktion in einzelne Felder zerbröseln und diese Mimik solltest du auch über die Forumssuchfunktion ein paarmal finden hier im Forum.

Gibt es denn gar keine andere Möglichkeit für dich, diesen Prozess anders zu gestalten, z.B. den "Datei-Erzeuger" irgendwie zu überreden, in einem für dich brauchbareren Format zu schreiben?

Dieses "Über-sieben-Brücken-musst-du-gehn"- ist doch eher was Tolles für Zahnärzte, aber doch nicht in unserem Job.

Grüße
Biber
ipzipzap
ipzipzap 07.05.2011 um 16:20:44 Uhr
Goto Top
So, ich habe mir jetzt mit Hilfe der Suche hier folgendes gebaut:


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

:processline

Set "Line=%line:&=§%"   

set     "var=date" & call:trim    %line:~0,10%  
set     "var=time" & Call:Trim    %line:~11,5%  
set  "var=company" & Call:Trim   %line:~82,45%  
set     "var=name" & call:trim  %line:~127,44%  
set       "var=nr" & call:trim  %line:~172,26%  

set "lineout1=%date%;%time%;%company%;%name%;%nr%  
Set "lineout2=%lineout1:§=^&%"   

Echo %lineout2% >> output.csv

:goto :eof

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

goto :eof

Jetzt habe ich aber gemerkt, das einige Namen auch Spitznamen in Anführungszeichen beinhalten, also z.B.

Max "TheBrain" Mustermann

Da bekomme ich natürlich Fehlermeldungen.
Wie kann ich das Anführungszeichen noch maskieren, filtern, etc?

Gruß,
Dino
ipzipzap
ipzipzap 07.05.2011 um 16:21:48 Uhr
Goto Top
Zitat von @Biber:
Gibt es denn gar keine andere Möglichkeit für dich, diesen Prozess anders zu gestalten, z.B. den
"Datei-Erzeuger" irgendwie zu überreden, in einem für dich brauchbareren Format zu schreiben?

Der Datei-Erzeuger ist ein externes System, das kann ich nicht so ohne weiteres dazu überreden, mal eben seine Logfile-Struktur zu ändern face-wink

cu,
Dino
Lochkartenstanzer
Lochkartenstanzer 07.05.2011 um 16:23:09 Uhr
Goto Top
cat "textdatei" | gawk ' { print $1 ";" $2 ";" $3 ";" $4 ";" $5 } ' | tee ausgabedatei.csv

wenn man Leerzeichen nur als Trenner hat.

Ansonsten

cat textdatei | sed -e "s/^\(.\{xxx\}\)/\1;/" | ... | tee ausgabedatei.csv

mit xxx als Zahl für die Spaltenposition, hinter der ein ";" gesetzt werden soll und mehrere passende sed-Befehle hintereinander.


Nachtrag: Und wenn man die überflüssigen Leerzeichen loswerden will beides kombinieren:

cat textdatei | sed -e "s/^\(.\{xxx\}\)/\1;/" | ... | gawk -F ";" ' { print $1 ";" $2 ";" $3 ";" $4 ";" $5 } ' | tee ausgabedatei.csv

sed, gawk und vieles andere findet sich in cygwin ( http://cygwin.com ).
Biber
Biber 07.05.2011 um 16:35:55 Uhr
Goto Top
Moin ipzipzap,

du könntest das "Feld" mit dem [Max "TheBrain" Mustermann] umformatieren in [Max 'TheBrain' Mustermann].
Das ginge schmerzfrei mit einer neuen Zeile 07
Set "Line=%line:"='%"

Ich würde das auch nicht wieder (zurücküb)ersetzen - denn Excel oder OpenOffice/LibreOffice oder sonstige Folgesysteme werden bei Texten mit eingebetteten Anführungszeichen genauso rumzicken.

Grüße
Biber
ipzipzap
ipzipzap 07.05.2011 um 17:00:30 Uhr
Goto Top
Zitat von @Biber:
Das ginge schmerzfrei mit einer neuen Zeile 07
> Set "Line=%line:"='%"

Danke, klappt soweit. Jetzt bleibt er wieder hängen, weil in diversen Firmennamen ein Pipe-Zeichen drin ist face-confused
Ein

Set "line=%line1:|=-%"

klappt aber nicht. Muß ich das noch maskieren?

Gruß,
Dino


EDIT: Klappt erstmal doch... mein Fehler face-wink

Hab aber schon wieder andere Sonderzeichen gefunden... melde mich gleich wieder ^^
bastla
bastla 07.05.2011 um 19:02:01 Uhr
Goto Top
Hallo ipzipzap!

Eine Umsetzung Deines Batch-Ansatzes in VBS (obwohl es sich eigentlich, wenn es ohnehin "Richtung Excel" geht, anbieten würde, gleich VBA zu verwenden und in die entsprechenden Spalten des Tabellenblattes zu schreiben) erspart Dir, Dich um Sonderzeichen kümmern zu müssen:
Ein = "input.txt"  
Aus = "output.csv"  
Delim = ";"  

Set fso = CreateObject("Scripting.FileSystemObject")  
T = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)

For i = 0 To UBound(T)
    T(i) = Trim(Mid(T(i),   1, 10)) & Delim & _
           Trim(Mid(T(i),  12,  5)) & Delim & _
           Trim(Mid(T(i),  83, 45)) & Delim & _
           Trim(Mid(T(i), 128, 44)) & Delim & _
           Trim(Mid(T(i), 173, 26))
Next

fso.CreateTextFile(Aus).Write Join(T, vbCrLf)
[Edit]
Übrigens: Es sollte sich doch sogar per Makro-Aufzeichnung ein direkter Import in Excel automatisieren lassen - Ergebnis (in VBA) etwa:
Sub Import()
Workbooks.OpenText Filename:="D:\input.txt", Origin:=xlMSDOS, _  
    StartRow:=1, DataType:=xlFixedWidth, FieldInfo:=Array(Array(0, 1), Array(10, 9), Array(11, 1), Array(16, 9), Array(82, 1), Array(127, 1), Array(172, 1), Array(199, 9))
End Sub
[/Edit]

Grüße
bastla
Biber
Biber 08.05.2011 um 00:31:22 Uhr
Goto Top
Moin bastla,

stimme deinem letzten Schluss "Excel-VBA-Lösung" vollkommen zu, hätte aber noch zwei Pingeligkeiten.

Erstens ist dein Schnipsel zwar vielleicht für Redmonder Makro-Recorder flüssig lesbar oder für Coder, die den ganzen Tag Bits und Bytes durch die Uhrmacherlupe betrachten.
Aber für Gelegenheits-Gebrauchsbätcher wie mich ist es so nicht pfleg- und wartbar.

Zweitens kommt as far as i see für die erste Spalte das falsche Datumsformat raus beim Import - Excel würde "05/07/2011" übersetzen als den 5.Juli 2011.
Gemeint ist aber der 7.Mai.

Also mein Vorschlag: ausgehend von dem etwas tristen Rekorderabgespule
Sub Import()
Workbooks.OpenText Filename:="D:\input.txt", Origin:=xlMSDOS, _  
    StartRow:=1, DataType:=xlFixedWidth, FieldInfo:=Array(Array(0, 1), Array(10, 9), Array(11, 1), Array(16, 9), Array(82, 1), Array(127, 1), Array(172, 1), Array(199, 9))
End Sub

würde ich es so in epische Breite auswalzen:

Sub ImportV2()
Workbooks.OpenText Filename:="D:\input.txt", Origin:=xlMSDOS, _  
    StartRow:=1, DataType:=xlFixedWidth, _
    FieldInfo:=Array( _
               Array(0, xlMDYFormat), _   ' Inputdatum kommt als MM/DD/YYYY  
               Array(10, xlSkipColumn), _ 
               Array(11, xlGeneralFormat), _
               Array(16, xlSkipColumn), _
               Array(82, xlGeneralFormat), _
               Array(127, xlGeneralFormat), _
               Array(172, xlGeneralFormat), _
               Array(199, xlSkipColumn) _
               )
End Sub

Grüße
Biber
bastla
bastla 08.05.2011 um 18:38:33 Uhr
Goto Top
Hallo Biber!
Zweitens kommt as far as i see für die erste Spalte das falsche Datumsformat raus beim Import
Jetzt, wo Du's sagst ... face-wink

Tatsächlich habe ich leider den Makro-Teil nur so en passant (und eher als Hinweis gedacht) rangeflanscht ... face-sad

Grüße
bastla