Seite 1 von 1

Lines aus Files mit verschiedenen Line endings extrahieren

Verfasst: Montag 5. März 2007, 11:12
von Francesco
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?

Verfasst: Montag 5. März 2007, 11:19
von nkoehring
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 ;)

Verfasst: Montag 5. März 2007, 11:59
von Luzandro
Du kannst re.split nehmen um mehrere Separator anzugeben

Code: Alles auswählen

re.split("\r\n|\n|\r", text)

Verfasst: Montag 5. März 2007, 12:17
von rayo
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

Verfasst: Montag 5. März 2007, 12:41
von Francesco
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()

Verfasst: Montag 5. März 2007, 12:43
von Luzandro
Hätt ich auch, wenn ichs nicht schon wieder vergessen hätte ;)

Verfasst: Montag 5. März 2007, 14:00
von Y0Gi
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.

Verfasst: Montag 5. März 2007, 14:48
von nkoehring
Also funktioniert das "rU" auch mit gemischten Dateien? ...bzw ist wohl direkt dafuer da, oder? Ich kannte das bisher nicht, danke :D

Verfasst: Montag 5. März 2007, 17:07
von Leonidas
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.