Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

I solved a more general problem that could be useful here:

How to parse big file line-by-line with any line delimiter (CR/CRLF/LF), but unknown beforehand.

'Big' file means that it is not ok to read the whole file into one variable. Here function 'detectEndOfLine' gets name of file and returns either '\r' or '\n', whatever is used for line ending (it searched for '\r' or '\n' symbol char-by-char starting from the end of the file).

my $file = "test.txt";
local $/ = detectEndOfLine($file);
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
while(<IN>) {
    s/\r\n|\n|\r$//;
    print "$_\n";
}

sub detectEndOfLine {
    my $file = $_[0];
    my $size = -s $file;
    print "\"$size\"\n";

    open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
    for(my $i = $size; $i >= 0; --$i) {
        seek(IN, $i, 0);
        $_ = <IN>;
        my $sym = substr($_, 0, 1);
        return $sym if( $sym eq "\n" or $sym eq "\r" );
    }
    return undef;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top