views:

79

answers:

1

I'm trying to read a file which has only CR as line delimiter. I'm using Mac OS X and Perl v.5.8.8. This script should run on every platform, for every kind of line delimiter (CR, LF, CRLF).

My current code is the following :

open(FILE, "test.txt");

while($record = <FILE>){
    print $record;
}

close(TEST);

This currently print only the last line (or worst). What is going on? Obvisously, I would like to not convert the file. Is it possible?

+6  A: 

You can set the delimiter using the special variable $/:

local $/ = "\r" # CR, use "\r\n" for CRLF or "\n" for LF
my $line = <FILE>;

See perldoc perlvar for further information.

Another solution that works with all kinds of linebreaks would be to slurp the whole file at once and then split it into lines using a regex:

local $/ = undef;
my $content = <FILE>;
my @lines = split /\r\n|\n|\r/, $content;

You shouldn't do that with very large files though, as the file is read into memory completely. Note that setting $/ to the undefined value disables the line delimiter, meaning that everything is read until the end of the file.

jkramer
Doesn't seem to work...
Subb
"\r" is just an example for CR, you might want to try "\r\n" and "\n" for CRLF and LF respectively.
jkramer
Oh I see. CR and Terminal don't play well together.
Subb
Your split has a bug. Perl will use the first matching branch in an alternation and only try later branches if it can't satisfy the full pattern. So if `$content` is `"a\r\nb"` the result of lines will be `('a', '', 'b')`. Rearranging the alternation to `/\r\n|\r|\n/` will produce the desire results, it can be simplified further to `/\r\n?|\n/`.
Ven'Tatsu
You're right, I fixed it. I usually just use /\r?\n/, but that wouldn't work with CR linebreaks. However, I've never seen CR-only linebreaks being used in practice before.
jkramer