Kategorien
Skripte Tutorial

Probleme mit Zeilenumbruch und Wagenrücklauf in Python 3

Falsche interpretierte Zeilenumbrüche sind ein Problem, das mir in meiner Tätigkeit immer wieder begegnet. Besonders häufig treten Sie auf, wenn man mit mehreren Betriebssystemen, sehr alten Programmiersprachen oder ungewöhnlichen Zeichenkodierungen zu tun hat.

Die beiden Bilder zeigen ein Worldfile, welches mit Python in einer UNIX-Umgebung (OSGEOlive) erzeugt wurde. In OSGEOlive und Windows 10 (WIN 10) wird die Datei korrekt angezeigt, auf einem Windows Server 2016 jedoch nicht.

Bild 1 – falsche Darstellung

Die Geschichte eines Problemes

Das Problem ist so alt wie die digitale Datenverarbeitung! Tatsächlich resultiert es aus der Zeit der Schreibmaschinen und Fernschreiber. Bei mechanischen Schreibmaschinen wurden der Wagenrücklauf (engl. carriage return) = <CR> = „\r“ und Zeilenvorschub (engl. Line feed) = <LF> = „\n“ in der Regel gemeinsam durch die Betätigung des Zeilenschalthebels ausgelöst, man spricht dann von einem Zeilenumbruch. Bei Fernschreibern wurden diese Operationen mit getrennten Steuerzeichen übermittelt. Dies war der dem, im Vergleich zum Zeichenanschlag, mechanisch bedingt, längerem Wagenrücklauf geschuldet. Darüber hinaus ermöglicht die Trennung auch die Übertragung komplexerer Textelemente, wie das Unterstreichen.

Ob eine Betriebssystem oder eine Programmiersprache nun den Wagenrücklauf „\r“ (wie beim C64), den Zeilenvorschub „\n“ (wie Linux) oder den Zeilenumbruch „\r\n“ (wie Windows) als Steuerzeichen für den von allen gemeinten Zeilenumbruch verwendet, ist also meist auf Entscheidungen in der frühen Entwicklung dieser Systeme zurück zu führen.

Python geht hier einen interessanten Weg. Sofern nichts anderes angegeben übersetzt die open()-Funktion beim Lesen alle herkömmlichen Zeilenumbruchzeichen für die interne Verwendung in „\n“. Beim Schreiben einer Datei wird das, für das jeweilige Betriebssystem auf dem das Python-Skript ausgeführt wird, standradmäßige Steuerzeichen für Zeilenumbrüche genutzt.

Lösung in Python

Wenn wie im oben beschriebenen Beispiel, eine Datei in einem anderen System weiterverarbeitet werden, so kann die open()-Funktion mit dem Attribut newline, zu der Nutzung eines andern Steuerzeichens gebracht werden.

01 import os
02 for file in os.listdir('./in'):
03    if file.endswith('.tfw'):
04	f = open('./in/'+file, "r")
05	text = f.read()
06	f = open('./out/'+file,"w",            
        newline="\r\n")
07	f.write(text)
08	f.close()

Link: https://docs.python.org/release/3.2/library/functions.html#open