cgicorner.ch

Informationen rund um Perl/CGI

Sie sind hier: Home > Knowledge Base > Windows: \n wird in Datei zu \r\n

Windows: \n wird in Datei zu \r\n

Perl läft auf einem Windows-System. Dort wird eine Datei mit UNIX-Zeilenumbrüchen geschrieben:

open(FILE,">test.txt");
print FILE "Zeile1\nZeile2";
close(FILE);

Die Datei hat nun aber PC-Zeilenumbrüche (Zeile1\r\nZeile2). Was mache ich falsch?

Beim Schreiben von Plaintext-Dateien stellt \n für Perl einen systemabhängigen Zeilenumbruch (unter Windows eben \r\n) dar. Dieser "logische Zeilenumbruch" ist keine spezifische Perl-Erfindung, sondern wird von der C-Runtime-Bibliothek, die von Perl verwendet wird, so verwendet.

Um diesen zu umgehen gibt es mehrere Möglichkeiten. Die einfachste ist der binmode Befehl:

open(FILE,">test.txt");
binmode FILE;
print FILE "Zeile1\nZeile2";
close(FILE);

Dadurch werden nur diegenigen Zeichen in die Datei geschrieben, welche auch explizit angegeben werden. Der "binmode"-Befehl muss für jeden Dateihandle separat angegeben werden.

Dadurch werden nur diegenigen Zeichen in die Datei geschrieben, welche auch explizit angegeben werden. Der "binmode"-Befehl muss für jeden Dateihandle separat angegeben werden. Einmal in den Binärmodus gewechselt kann dieser nicht wieder zurückgesetzt werden.

Eine zweite Möglichkeit besteht im use open OUT => ':raw'; Befehl. Dieser schreibt generell nur die angegebenen Zeichen in alle Output-Dateien. Anders als "binmode" funktioniert dieser Befehl aber nicht mit allen Perl-Versionen (mittlerweile jedoch eine gute Verbreitung). Auch hier ein Beispiel

use open OUT => ':raw';

open(OUTPUT, ">test.txt");
print OUTPUT "test\ntest2";
close(OUTPUT);

open(OUTPUT2, ">test2.txt");
print OUTPUT2 "test\ntest2";
close(OUTPUT2);

Perl hat auch zwei Systemvariablen $/ und $\ für das In- und Output-Zeilenformat. Wird beispielswiese die Input-Variable $/ auf den Mac-Zeilenumbruch gesetzt, wird die Datei in einer While-Schleife beim \r eingelesen. Beispiel:

$/="\r";
open(INPUT, "test.txt");
while () {
  chomp;
  print "Zeile: ".$_."\n";
}
close(INPUT);

Die Variable $\ definiert einen String, der jedem Print-Befehl angefügt wird:

#!/usr/bin/perl
$\="ENDE\n";
open(OUTPUT, ">test.txt");
print OUTPUT "Zeile 1";
print OUTPUT "Zeile 2";
print OUTPUT "Zeile 3";
close(OUTPUT);

Wichtig: Das Setzen der Variable $\ setzt 1) keine \n um, sondern wird nur an jeden Print-Befehl angehängt und setzt 2) ebenfalls logische Zeilenumbrücke ein, d.h. ein $\="\n" schreibt in die Datei unter Windows wiederum ein "\r\n". Die Systemvariablen $/ und $\ eignen sich also NICHT, um die \r-Problematik unter Windows bei Ausgabedateien zu lösen.

Weiterführende Links

Autor: Jürg Sommer, knowledge@cgicorner.ch

[ zurück ]