in reply to finding different linebreaks with <>

Yes, that's the Mac method of breaking lines - you get that one you transfer their text file in binary mode. If you just want to read the file, you can do: local $/="\cM"; and read it like normal. Or you could slurp it in:
$wholefile=join("",<FILE>); $wholefile=~tr/\cM/\n/; print CONVERTED $wholefile;
which will give you the file transformed (but don't do slurp for large files like logs).

Replies are listed 'Best First'.
Re: Re: finding different linebreaks with <>
by revdiablo (Prior) on Apr 08, 2004 at 20:00 UTC

    I would think about either using the more efficient idiomatic slurp (i.e. my $wholefile = do { local (@ARGV, $/) = $filename; <> };) or using the excellent and even more efficient File::Slurp module.

Re: Re: finding different linebreaks with <>
by seaver (Pilgrim) on Apr 08, 2004 at 20:02 UTC
    OK, cool thank you for your prompt replies.
    So, i finally get the file to output, line by line, with this code:

    #!/usr/bin/perl - w use strict; local $/="\cM"; my $file = $ARGV[0]; open my $fh, '<', $file or die $!; while(<$fh>){ print $_."\n"; }

    I had to add the "\n" to the end of each line so that it printed out correctly in the unix system, the reason given by you guys

    However, what if my file could be EITHER *nix/mac or windows, what's the best way to tell??

    I'm hoping you can use a regular expression with the '$/' and do something like this:

    local $/ = "[\n\r\cM]";

    which then gets regexp for any or either, does that make sense?

    Cheers
    Sam

      You can do exactly what you asked for with File::Stream. A moderately portable regular expression to use is qr/\r\n?|\n\r?/. That should handle Unix, DOS and MacOS line endings on any of those three platforms.
        Dear Tilly,

        Thanks so much for your help, I've downloaded and used File::Stream to great success. I'm using the regular expression below:

        my ($handler, $stream) = File::Stream->new(\*FILE, separator => qr{[\c +M\r\n][\cM\r\n]?});

        Does anyone see any pitfalls with this one? I wanted to make sure I got all three 'types' of characters.

        Thanks
        Sam

      Sorry, no regexen are allowed in $/.

      The best solution is to convert the data file into a consistant form before the main program gets it.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

        no regexen are allowed in $/.

        You missed a chance to quote perlvar:

        Remember: the value of $/ is a string, not a regex. awk has to be better for something. :-)


        ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
        =~y~b-v~a-z~s; print
        I understand, that I will do, thanks for your help
        Sam
      Nope, no regexes for $/. If the file isn't too large or performance isn't too critical, you could do something like (untested, and requires 5.8.0):
      open my $fh, "filename" or die $!; while (my $line = <$fh>) { local $/ = "\r"; open my $fh, "<", \$line or die $!; while (my $line = <$fh>) { # process $line here } }
      Otherwise, open the file and read a bunch of characters (e.g. by setting $/=\1024; see perldoc perlvar) and check for \n or \r (e.g. with $/ = $1 if $buffer=~/([\r\n])/;)and set $/ appropriately; then seek to the beginning of the file and start the read loop.