Lines aus Files mit verschiedenen Line endings extrahieren

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
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Montag 5. März 2007, 11:12

Hallo,
folgende Sache:

Ich habe files die entweder in linux zeilenende oder windows zeilen ende
oder auch gemischt vorliegen.

Ich möchte jede Zeile extrahieren und dabei eine Liste von Zeilenstrings haben. Also eine Art universelles split.
Schön wäre es eine einzige kleine kompakte Funktion zu haben.

Beispiel:

file:

Code: Alles auswählen

  entry1    <lf>
entry2   <crlf>
  entry31   <lf>
<lf>
<crlf>
list: ["entry1", "entry2", "entry3"] ohne whitespace

Eigentlich einfach, würde es schon zusammenbringen (hoffe ich), aber effiziente und kurze funktion.

Ausserdem: Nur bei "binary" open wird in windows \n eingefügt,
sonst mit normalen öffnen wird beim '\n' \r\n' eingefügt.

Die eine Funktion soll unter linux UND Windows funktionieren und die entries am shluss (leerzeilen wie oben sichtbar) ignorieren bzw. wegextrahieren


Oder hätte das verwenden von 'U' für Universal irgendwelche Vorteile?
Zuletzt geändert von Francesco am Montag 5. März 2007, 17:16, insgesamt 1-mal geändert.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Montag 5. März 2007, 11:19

versteh ich das richtig... du willst Textdateien einlesen, die Windows- UND Unix-Lineendings haben? Wo gibts denn sowas ^^

Naja, also ich wuerde sagen, du schreibst eine Funktion, die die Datei Binaer oeffnet, und komplett einließt (.write()). Das eingelesene kannst du dann ja zuerst nach '/n' spitten, dann jeden Teil der neuen Liste mit rstrip('\r') vom '\r' befreien und danach (um auch Mac zu beachten) nochmal alles mit split('\r') splitten und die Liste wieder zusammenfuehren.


MfG

EDIT:
Habs mal probiert... es ist nicht perfekt, aber funktioniert soweit ganz gut:

mein testscript

Code: Alles auswählen

def create(name="bla.txt"):
        TXT = "Hello world...\r I'm a long text with totally strange lineterminators.\r\nThats why somebody wanted,\nthat I look like a mixture of\r\nWindoze\nUnix and\rMac file...\x20"
        F = file(name, "wb")
        F.write(TXT)
        F.close()
        return True

def read(name="bla.txt"):
        F = file(name, "rb")
        data = F.read()
        F.close()
        
        data = data.split('\n')
        for part in data: part.rstrip('\r')
        tmp = list()
        for part in data:
                part = part.split('\r')
                tmp += part
        data = tmp

        return data

if __name__ == '__main__': print '\n'.join(read())
natuerlich sollte man am ende linesep benutzen und sowas... aber es ist ja nur ein test ;)
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Montag 5. März 2007, 11:59

Du kannst re.split nehmen um mehrere Separator anzugeben

Code: Alles auswählen

re.split("\r\n|\n|\r", text)
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Montag 5. März 2007, 12:17

Hi

Verwende doch 'rU' beim öffnen, damit wandelt Python alle newlines zu \n, egal ob es \r\n oder \r war, in deinem Programm sind es immer \n.

Code: Alles auswählen

f = open('test','wb')
f.write('1. Linie \n2. Linie \r\n3. Linie \r4. Linie')
f.close()

f = open('test','rU')
for x in f:
    print repr(x)
f.close()
Gruss
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Montag 5. März 2007, 12:41

Danke Euch allen, ich nehme
die Lösung von rayo, gefällt mir am besten und ist am einfachsten.

Also:

Code: Alles auswählen

f = open('testfilemixed.txt','rU')
elements = [x.strip() for x in f]
#print elements
f.close()
Zuletzt geändert von Francesco am Montag 5. März 2007, 12:44, insgesamt 1-mal geändert.
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Montag 5. März 2007, 12:43

Hätt ich auch, wenn ichs nicht schon wieder vergessen hätte ;)
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 5. März 2007, 14:00

Alternativ kann man die Datei im Binärmodus öffnen, über den Iterator Zeilenweise lesen und mit .strip() die Zeilenenden abschneiden. Allerdings habe ich gerade Zweifel, ob das nur mit \r in Mac-Dateien auch so funktioniert.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Montag 5. März 2007, 14:48

Also funktioniert das "rU" auch mit gemischten Dateien? ...bzw ist wohl direkt dafuer da, oder? Ich kannte das bisher nicht, danke :D
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 5. März 2007, 17:07

nkoehring hat geschrieben:Ich kannte das bisher nicht, danke :D
Habe ich erst gestern und ähm.. gestern verlinkt. Einfach mal den zugehörigen PEP lesen, der erklärt recht einfach wozu Universal Newline Support ist.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten