Ooops has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
I'm working on linux and win32 machines. This routine parses mostly big LOG files, often from the *other* OS. The files contain ether \r\n or \n as EOL and may not be changed.
I have written a routine, which uses Tie::File in RO mode to get the lines. But this proggy dies if it ties an single-element-array which happens when getting newline text while running under win32.
Any suggestions?

# $/ = "\x0d\x0a" # this is default (OS = Win32) tie my @array, 'Tie::File', $file, mode => O_RDONLY, memory => 0 or di +e $!; # ReadOnly und *no MemBuffer* !! # $_ =~ s/\r?\n/\n/g for (@array); # doesn't work because $file will +be written $n_recs = @array; # how many records/lines are in the file? unless ($n_recs > 1) { untie @array; local $/ = "\x0a"; tie @array, 'Tie::File', $datei, mode => O_RDONLY, memory => 0 or d +ie $!; $n_recs = @array; print join ("~LF~", @array); # test to see... die "Sorry -- only one line!\n" unless $n_recs > 1; }

Replies are listed 'Best First'.
Re: Problems with changing $/ and Tie::File in RO mode (:crlf)
by almut (Canon) on Oct 01, 2009 at 14:24 UTC

    As an alternative to your approach, you might want to look into PerlIO, in particular the :crlf layer, which is responsible for Perl's different handling of newlines on Windows vs. Unix:

    :crlf
    A layer that implements DOS/Windows like CRLF line endings. On read converts pairs of CR,LF to a single "\n" newline character. On write converts each "\n" to a CR,LF pair. (...)

    By default, that layer is active on Windows perls, but nothing is keeping you from using the layer on Unix to read Windows-style text files, or removing the layer on Windows to write Unix-style files.

      Hi almut,
      you are right, this is interesting and I'm going to study on that, but does it also work with the 'Tie::File' to an @array? (If so, what do I have to code?)
      The advantage of 'Tie'ing in my way is to use zero memory, because I do not read the file into RAM.

        does it also work with the 'Tie::File' to an @array?

        Yes.  For example, to read Windows-style files on Unix:

        #!/usr/bin/perl use Tie::File; my $fname = shift @ARGV; open my $fh_crlf, "<:crlf", $fname or die "Couldn't open '$fname': $!" +; tie my @array, 'Tie::File', $fh_crlf, mode => O_RDONLY, memory => 0 or + die $!; for my $line (@array) { # ... # $line has no trailing \r }