zeilenumbrüche in einer csv-datei entfernen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

hallo zusammen,

ich würde gerne die Zeilenumbrüche einer csv-datei entfernen. Dies wollte ich mit folgendem Befehl machen

Code: Alles auswählen

open("/home/susanne/Desktop/outlook.csv", "r").read().replace("\n", ", ").close()
leider kommt folgende Fehlermeldung:
'str' object has no attribute 'close'

kann mir jemand sagen was ich falsch mache?

vielen Dank im voraus
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

.read() gibt ein str-Objekt zurück, das hat dann die entsprechende Methode .close nicht. Du kannst die Aufrufe der Funktionen also nicht einfach aneinander reihen.
Willst du das Ergebnis auch in der Datei speichern?
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

ja, ich würde gerne die Datei öffnen, die Zeilenumbrüche entfernen, die Datei dann wieder schließen und abspeichern
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

1. Öffne die bisherige Datei zum Lesen, beginne einen with-Block
2. Lese in dem with-Block den Inhalt
3. Nimm nach Veralssen des With-Blocks die Änderungen in den Daten vor
4. Öffne eine neue Datei mit neuem Dateinamen im bisherigen Verzeichnis, beginne einen with-Block
5. Schreibe die geänderten Daten in dem with-Block in die Datei
6. Lösche nach dem With-Block die alte Datei
7. Benenn die neue Datei mit dem Dateinamen um.
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

und wie sieht sowas in einem code aus?
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Du meinst so etwas hier:

Code: Alles auswählen

inputfile = "test.txt"
outputfile = "test-neu.txt"

with open(inputfile, "r") as f, open(outputfile, "w") as g:

    for line in f:

        line.replace("\n", ", ")

        g.write(line)
Ich sehe gerade, dass das hier dir nicht hilft, aber es geht vergleichbar:

Code: Alles auswählen

inputfile = "test.txt"
outputfile = "test-neu.txt"


daten = []


with open(inputfile, "r") as f:

    for line in f:

        line.replace("\n", ", ")

        daten.append(line)


with open(outputfile, "w") as g:

    daten = "".join(daten)
    
    g.write(daten)
Allerdings leistet das Programm gerade nicht das gewünschte Ergebnis, was mich wundert. Schau mal, ob du mit den beiden Codeblöcken weiterkommst. Sie sollten verständlich sein.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Susanne

Hier noch sparrow's Vorschlag in codierter Form:

Code: Alles auswählen

import os

'''
Die Datei "alte_vcs.txt" enthält als Input folgende Daten:
String-1
String-2
String-3
String-4

Als Output:
String-1, String-2, String-3, String-4,
'''

with open("alte_vcs.txt", 'r') as input_file:
    data = input_file.read()
    
data = data.replace("\n", ", ")

with open("neue_vcs.txt", 'w') as output_file:
    output_file.write(data)

os.remove("alte_vcs.txt")
os.rename("neue_vcs.txt", "alte_vcs.txt")
Our forum is your solution provider

Gruß wuf :wink:
Take it easy Mates!
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

Hallo und Danke nochmals des hat soweit funktioniert.
allerdings hab ich schon das nächste Problem:

ich will ja die Outlook Kontakte in einer Datenbank abspeichern. Das csv-File sieht wie folgt aus:
"Anrede","Vorname","Weitere Vornamen","Nachname","Suffix","Firma","Abteilung","Position","Strasse geschaeftlich","Strasse geschaeftlich 2","Strasse geschaeftlich 3","Ort geschaeftlich","Region geschaeftlich","Postleitzahl geschaeftlich","Land/Region geschaeftlich","Strasse privat","Strasse privat 2","Strasse privat 3","Ort privat","Bundesland/Kanton privat","Postleitzahl privat","Land/Region privat","Weitere Strasse","Weitere Strasse 2","Weitere Strasse 3","Weiterer Ort","Weiteres/r Bundesland/Kanton","Weitere Postleitzahl","Weiteres/e Land/Region","Telefon Assistent","Fax geschaeftlich","Telefon geschaeftlich","Telefon geschaeftlich 2","Rueckmeldung","Autotelefon","Telefon Firma","Fax privat","Telefon privat","Telefon privat 2","ISDN","Mobiltelefon","Weiteres Fax","Weiteres Telefon","Pager","Haupttelefon","Mobiltelefon 2","Telefon fuer Hoerbehinderte","Telex","Abrechnungsinformation","Benutzer 1","Benutzer 2","Benutzer 3","Benutzer 4","Beruf","Buero","E-Mail-Adresse","E-Mail-Typ","E-Mail: Angezeigter Name","E-Mail 2: Adresse","E-Mail 2: Typ","E-Mail 2: Angezeigter Name","E-Mail 3: Adresse","E-Mail 3: Typ","E-Mail 3: Angezeigter Name","Empfohlen von","Geburtstag","Geschlecht","Hobby","Initialen","Internet-Frei/Gebucht","Jahrestag","Kategorien","Kinder","Konto","Name Assistent","Name des/der Vorgesetzten","Notizen","Organisationsnr.","Ort","Partner","Postfach geschaeftlich","Postfach privat","Prioritaet","Privat","Regierungsnr.","Reisekilometer","Sprache","Stichwoerter","Vertraulichkeit","Verzeichnisserver","Webseite","Weiteres Postfach"
"","Guido","","Maier","","","","","",,,"","","","Deutschland",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"0.0.00","Keine Angabe",,"G.S.",,"0.0.00","",,"",,,"
",,"",,,,"Normal","Aus",,,"","","Normal"
"","Annemarie","","Müller","","","","","",,,"","","","Deutschland",,,,,,,,,,,,,,,,"","","",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"0.0.00","Keine Angabe",,"A.H.",,"0.0.00","",,"",,,"
",,"",,,,"Normal","Aus",,,"","","Normal"


Allerdings wird nun nur noch der Header der csv-datei abgespeichert nicht mehr die Namen. In meinem Beispiel bedeutet das, dass die Daten vom "Guido" und von der "Annemarie" nicht eingetragen werden.

Hier unten ist mein code:

Code: Alles auswählen

 reader = csv.reader(open("/home/susanne/Desktop/"+filename),delimiter=",")
            for global_row in reader:
                Anrede = global_row[0]
                Vorname = global_row[1]
                WeitereVornamen = global_row[2]
                Nachname = global_row[3]
                Suffix = global_row[4]
                Firma = global_row[5]
                Abteilung = global_row[6]
                Position = global_row[7]
                Strassegeschaeftlich = global_row[8]
                Strassegeschaeftlich2 = global_row[9]
                Strassegeschaeftlich3 = global_row[10]
                Ortgeschaeftlich = global_row[11]
                Regiongeschaeftlich = global_row[12]
                Postleitzahlgeschaeftlich = global_row[13]
                LandRegiongeschaeftlich = global_row[14]
                Strasseprivat = global_row[15]
                Strasseprivat2 = global_row[16]
                Strasseprivat3 = global_row[17]
                Ortprivat = global_row[18]
                BundeslandKantonprivat = global_row[19]
                Postleitzahlprivat = global_row[20]
                LandRegionprivat = global_row[21]
                WeitereStrasse = global_row[22]
                WeitereStrasse2 = global_row[23]
                WeitereStrasse3 = global_row[24]
                WeitererOrt = global_row[25]
                WeiteresBundeslandKanton = global_row[26]
                WeiterePostleitzahl = global_row[27]
                WeiteresLandRegion = global_row[28]
                TelefonAssistent = global_row[29]
                Faxgeschaeftlich = global_row[30]
                Telefongeschaeftlich = global_row[31]
                Telefongeschaeftlich2 = global_row[32]
                Rueckmeldung = global_row[33]
                Autotelefon = global_row[34]
                TelefonFirma = global_row[35]
                Faxprivat = global_row[36]
                Telefonprivat = global_row[37]
                Telefonprivat2 = global_row[38]
                ISDN = global_row[39]
                Mobiltelefon = global_row[40]
                WeiteresFax = global_row[41]
                WeiteresTelefon = global_row[42]
                Pager = global_row[43]
                Haupttelefon = global_row[44]
                Mobiltelefon2 = global_row[45]
                TelefonfuerHoerbehinderte = global_row[46]
                Telex = global_row[47]
                Abrechnungsinformation = global_row[48]
                Benutzer1 = global_row[49]
                Benutzer2 = global_row[50]
                Benutzer3 = global_row[51]
                Benutzer4 = global_row[52]
                Beruf = global_row[53]
                Buero = global_row[54]
                EMailAdresse = global_row[55]
                EMailTyp = global_row[56]
                EMailAngezeigterName = global_row[57]
                EMail2Adresse = global_row[58]
                EMail2Typ = global_row[59]
                EMail2AngezeigterName = global_row[60]
                EMail3Adresse = global_row[61]
                EMail3Typ = global_row[62]
                EMail3AngezeigterName = global_row[63]
                Empfohlenvon = global_row[64]
                Geburtstag = global_row[65]
                Geschlecht = global_row[66]
                Hobby = global_row[67]
                Initialen = global_row[68]
                InternetFreiGebucht = global_row[69]
                Jahrestag = global_row[70]
                Kategorien = global_row[71]
                Kinder = global_row[72]
                Konto = global_row[73]
                NameAssistent = global_row[74]
                NamedesderVorgesetzten = global_row[75]
                Notizen = global_row[76]
                Organisationsnr= global_row[77]
                Ort = global_row[78]
                Partner = global_row[79]
                Postfachgeschaeftlich = global_row[80]
                Postfachprivat = global_row[81]
                Prioritaet = global_row[82]
                Privat = global_row[83]
                Regierungsnr = global_row[84]
                Reisekilometer = global_row[85]
                Sprache = global_row[86]
                Stichwoerter = global_row[87]
                Vertraulichkeit = global_row[88]
                Verzeichnisserver = global_row[89]
                Webseite = global_row[90]
                WeiteresPostfach = global_row[91]



                a = Address(Anrede=Anrede, Vorname=Vorname, WeitereVornamen=WeitereVornamen, Nachname=Nachname, Suffix=Suffix, Firma=Firma, Abteilung=Abteilung, Position=Position, Strassegeschaeftlich=Strassegeschaeftlich, Strassegeschaeftlich2=Strassegeschaeftlich2, Strassegeschaeftlich3=Strassegeschaeftlich3, Ortgeschaeftlich=Ortgeschaeftlich, Regiongeschaeftlich=Regiongeschaeftlich, Postleitzahlgeschaeftlich=Postleitzahlgeschaeftlich, LandRegiongeschaeftlich=LandRegiongeschaeftlich, Strasseprivat=Strasseprivat, Strasseprivat2=Strasseprivat2, Strasseprivat3=Strasseprivat3, Ortprivat=Ortprivat, BundeslandKantonprivat=BundeslandKantonprivat, Postleitzahlprivat=Postleitzahlprivat, LandRegionprivat=LandRegionprivat, WeitereStrasse=WeitereStrasse, WeitereStrasse2=WeitereStrasse2, WeitereStrasse3=WeitereStrasse3, WeitererOrt=WeitererOrt, WeiteresBundeslandKanton=WeiteresBundeslandKanton, WeiterePostleitzahl=WeiterePostleitzahl, WeiteresLandRegion=WeiteresLandRegion, TelefonAssistent=TelefonAssistent, Faxgeschaeftlich=Faxgeschaeftlich, Telefongeschaeftlich=Telefongeschaeftlich, Telefongeschaeftlich2=Telefongeschaeftlich2, Rueckmeldung=Rueckmeldung, Autotelefon=Autotelefon, TelefonFirma=TelefonFirma, Faxprivat=Faxprivat, Telefonprivat=Telefonprivat, Telefonprivat2=Telefonprivat2, ISDN=ISDN, Mobiltelefon=Mobiltelefon, WeiteresFax=WeiteresFax, WeiteresTelefon=WeiteresTelefon, Pager=Pager, Haupttelefon=Haupttelefon, Mobiltelefon2=Mobiltelefon2, TelefonfuerHoerbehinderte=TelefonfuerHoerbehinderte, Telex=Telex, Abrechnungsinformation=Abrechnungsinformation, Benutzer1=Benutzer1, Benutzer2=Benutzer2, Benutzer3=Benutzer3, Benutzer4=Benutzer4, Beruf=Beruf, Buero=Buero, EMailAdresse=EMailAdresse,EMailTyp=EMailTyp, EMailAngezeigterName=EMailAngezeigterName, EMail2Adresse=EMail2Adresse, EMail2Typ=EMail2Typ, EMail2AngezeigterName=EMail2AngezeigterName, EMail3Adresse=EMail3Adresse, EMail3Typ=EMail3Typ, EMail3AngezeigterName=EMail3AngezeigterName, Empfohlenvon=Empfohlenvon, Geburtstag=Geburtstag, Geschlecht=Geschlecht, Hobby=Hobby, Initialen=Initialen, InternetFreiGebucht=InternetFreiGebucht, Jahrestag=Jahrestag, Kategorien=Kategorien, Kinder=Kinder, Konto=Konto, NameAssistent=NameAssistent, NamedesderVorgesetzten=NamedesderVorgesetzten, Notizen=Notizen, Organisationsnr=Organisationsnr, Ort=Ort, Partner=Partner, Postfachgeschaeftlich=Postfachgeschaeftlich, Postfachprivat=Postfachprivat, Prioritaet=Prioritaet, Privat=Privat, Regierungsnr=Regierungsnr, Reisekilometer=Reisekilometer, Sprache=Sprache, Stichwoerter=Stichwoerter, Vertraulichkeit=Vertraulichkeit, Verzeichnisserver=Verzeichnisserver, Webseite=Webseite, WeiteresPostfach=WeiteresPostfach)

                a.save()
           


kann mir jemand sagen wie ich meine Schleife programmieren muss dass immer alle Einträge in die Datenabk kommen?
es könnte ja sein, dass ein Eintrag weg fällt bzw. einer dazu kommt.

vielen Dank im voraus
BlackJack

@Susanne: Den Header willst Du doch eigentlich gar nicht in der Datenbank haben. Würde ich jedenfalls nicht wollen. Also sollte man den am Anfang überlesen, zum Beipsiel in dem man auf den `reader` die `next()`-Funktion anwendet ohne sich für das Ergebnis zu interessieren, bevor man mit einer Schleife über den Rest geht.

Die Frage ist, ob es da überhaupt einen Rest gibt, denn wenn Du tatsächlich *alle* Zeilenumbrüche aus der Datei entfernt hast, dann sind da auch welche dabei die eigentlich wichtig gewesen wären um die Datensätze zu trennen. Mehr noch: Es kann in CSV-Dateien auch Zeilenumbrüche geben, die innerhalb von Datensätzen beziehungsweise Feldern stehen. Damit kann man noch nicht einmal sagen man fasst immer n Zeilen aus der Datei mit den vielen Zeilenumbrüchen zu einem Datensatz zusammen, sondern muss das wirklich als CSV-Datei mit *einer* Datenspalte auffassen und parsen, und immer n „Datensätze” zu einem neuen Datensatz zusammenfassen, wenn man auf der sicheren Seite sein möchte. Und gerade bei dieser Art von Daten können in Adressen oder Notizen durchaus Umbrüche vorkommen. Das wäre hier nichts exotisches.

Statt sich mit dieser Datei auseinander zu setzen, wäre es vielleicht eine gute Idee die Daten aus Outlook noch einmal zu exportieren und dann gleich im richtigen Format.
Sirius3
User
Beiträge: 17739
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Susanne,

Dein Header hat 92, alle weiteren Zeilen aber nur 89 Einträge. Warum Outlook beim Export ein paar Spalten wegläßt, bleibt wohl ein Geheimnis. Ansonsten scheint die Datei auch mit oder gerade wegen den Zeilenumbrüchen völlig in Ordnung zu sein. Du hast ja schon die Datenbankfelder nach den Headerfeldern benannt und nur Leerzeichen, -, ., / usw. entfernt. Dann nutze doch diese Information auch:

Code: Alles auswählen

import re
import csv
with open("/home/susanne/Desktop/outlook.csv", "r") as addressen:
    reader = csv.reader(addressen)
    header = [re.sub(r'\W','', key) for key in next(reader)]
    for addresse in reader:
        eintrag = dict(zip(header,addresse))
        Address(**eintrag).save()
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

ersetzen diese Programmzeilen nun mein ganzen Code?

Code: Alles auswählen

import re
import csv
with open("/home/susanne/Desktop/outlook.csv", "r") as addressen:
    reader = csv.reader(addressen)
    header = [re.sub(r'\W','', key) for key in next(reader)]
    for addresse in reader:
        eintrag = dict(zip(header,addresse))
        Address(**eintrag).save()
kann mir jemand die Zeilen erklären?
vor allem die Zeile:
Address(**eintrag).save()
was bedeuten die "**"

sorry bin Python Anfängerin.... will aber irgendwann auch mal so gut wie ihr sein :-)
darum frag ich :-)
Sirius3
User
Beiträge: 17739
Registriert: Sonntag 21. Oktober 2012, 17:20

Bei einem Funktionsaufruf Address(Anrede=anrede, ...) ist Anrede ein sogenannter Keyword-Parameter,
ein Parameter, der über seinen Namen angesprochen wird. **eintrag sagt nun, dass die Parameter nicht explizit sondern variabel über ein Dictionary angegeben werden.
Die header=-Zeile nimmt die erste Zeile aus der csv-Datei und wandelt die Spaltennamen in Datenbank-Spaltennamen um. zip(header,adresse) packt jeweils einen Spaltennamen mit dem Inhalt zusammen um daraus ein Dictionary zu erzeugen. Fehlende Spalten am Ende werden einfach ignoriert.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Susanne hat geschrieben:sorry bin Python Anfängerin.... will aber irgendwann auch mal so gut wie ihr sein :)
Das ist eine gute Einstellung :!:
Hier noch mal mit anderen Worten:

Code: Alles auswählen

Address(**eintrag)
'eintrag' ist ein Dictionary. Wenn Du nur

Code: Alles auswählen

Address(eintrag)
schreiben würdest, dann würde an Address (d.h. an Address.__init__()) nur ein Parameter, nämlich das Label des Dictionary, übergeben werden. Die Verwendung von '**eintrag' "entpackt" das Dictionary in named-Parameter, d.h. in alle key-value Elemente, die in dem Dictionary enthalten sind - so als wenn Du jedes Element als separaten Wert übergeben würdest; wie z.B. Anrede="Frau".
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

Hallo nochmals,

ich lese mit diesem Code daten aus einem csv-File in meine Datenbank:

Code: Alles auswählen

    with open("/home/susanne/Desktop/Kontakte.CSV", "r") as addressen:
        reader = csv.reader(addressen)
        header = [re.sub(r'\W','', key) for key in next(reader)]
        for addresse in reader:
            print addresse
            eintrag = dict(zip(header,addresse))
            Address(**eintrag).save()

leider liest er unendlich ein, d.h. das File wird immer wieder von vorne eingelesen. komisch ist auch, dass die Kontakte die mit A beginnen ca 100 mal eingetragen werden und die Kontakte die mit Z beginnen nur 3-4mal jenachdem wie lang das script läuft, ich habe das Gefühl als würde sich das >Script rekursiv aufrufen, was auch erklären wurde, warum Namen mit "A" 100X eingetragen werden und Namen mit "Z" nur einmal

kann mir jemand sagen was ich falsch mache?

vielen Dank
Sirius3
User
Beiträge: 17739
Registriert: Sonntag 21. Oktober 2012, 17:20

an welcher Stelle im Programm rufst Du denn die Leseroutine auf?
BlackJack

@Susanne: Falls das Skript sich irgendwo rekursiv aufruft, dann solltest Du das sein lassen. Das wäre dann nämlich ein Fehler. Was hast Du denn jetzt bei der Informationslage als Antwort erwartet?
Antworten