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

All i have a file and all the lines in the file which was created on windows, and is now on unix when i run the following.
while(<FH>){ printf("Found : $_\n"); }
When it prints out information it prints out the whole file as one line. ie
Found 1 06/02/23 11:16:05:390 Inbound:, Outbound:, Bidirectional:*** 2 06/02/23 11:16:05:390 Received FIX message Message dump: 3 06/02/23 11:16:05:390 Resetting FIX session intraday. 4 06/02/23 11:16:05:406 Sent FIX Message Message dump: 5 06/02/23 11:16:35:109 Sent FIX Message Message dump: 6 06/02/23 11:16:37:234 Received FIX message Message dump: 7 06/02/23 11:16:37:234 Sent FIX Message Message dump:
Is there a way to solve this.

Replies are listed 'Best First'.
Re: File lines being treated as one.
by GrandFather (Saint) on Mar 03, 2006 at 09:23 UTC

    It's not clear what your problem is actually. However an important thing you need to know is that Unix and Windows use different line end conventions. Normally Perl takes care of the convention for the current platform and you needn't worry about it. However if you are dealing with a file from a different platform then the differences can be important.

    Unix uses a line feed character (\n) as a line end indicator, Windows uses a carriage return line feed pair (\r\n) and the Mac uses a carriage return character (\r).

    It's not clear from your description just what your problem is, but you could try stripping \r characters from your file and see if that fixes the problem.


    DWIM is Perl's answer to Gödel
      Okay so when i read each line of a file created on windows it should end with \r\n. So to split out each line i could say split(/\r\n/,$file);

      The problem i have is that i am trying to search and file for certain values like.
      open(FF, "$fixmessageloc"); while(<FF>){ chomp($_); if($_ =~ /35=D/){ printf("Found $_\n"); } } <code> Now this will return . <code> Found 1 06/02/23 11:16:05:390 Inbound:, Outbound:, Bidirectional:*** 2 06/02/23 11:16:05:390 Received FIX message Message dump: 3 06/02/23 11:16:05:390 Resetting FIX session intraday. 4 06/02/23 11:16:05:406 Sent FIX Message Message dump: 5 06/02/23 11:16:35:109 Sent FIX Message Message dump: 6 06/02/23 11:16:37:234 Received FIX message Message dump: 7 06/02/23 11:16:37:234 Sent FIX Message Message dump: 8 06/02/23 11:16:37:265 Inbound:, Outbound:, Bidirectional:*** 9 06/02/23 11:16:44:671 Received FIX message Message dump:
      Which is the whole file, and not the line i want.

        Check that the input record seperator $/ hasn't been altered. You could:

        local $/ = "\n"; while (<FF>) {

        to make sure. Otherwise reduce the code to a minimum that demonstrates the problem and post the complete code. You shouldn't need more than about another two or three lines of code more than your current sample. Also, make sure you are using strictures: use strict; use warnings;


        DWIM is Perl's answer to Gödel
        So this is strange, when i run this code on the file on its own away from what i am trying to do.
        #!/usr/bin/perl my $file = shift; open (LOG, "<$file"); my $tag1 = "11=Order53:1:1140693468"; @logarray=<LOG>; foreach(@logarray){ if(($_=~ m/35=8/)&&($_ =~ m/$tag1/)){ printf ("$_\n"); } }
        I get the result i am looking for all be it away from what i am trying to do.
        $ perl t.pl fix.log 8=FIX.4.29=034435=849=EXLINK_COMPLEX56=COMPLEX_EXLINK50=COMPLEXGATE57= +DBL9991134=552=20060223-11:18:3 31=L6096=0.000011=Order53:1:114069346814=0.000017=1118339840020=031=0. +0000000032=0.000037=132710014138=1.000039=054=155=Tester60=20060223-1 +1:18:33150=0151=1.0000109=Test23=0167=FUT200=200603207=Test 40=144=0.0000000010=026 $

        But in my main code , all i do is call this routine and ask it to search for the file for the same entries as above, and return the results.

        sub readfile() { my($tag1,$tag2) = @_; open(FF, "<$fixmessageloc") || die ("Unable to open file: $!: readfil +e_rt \n"); my @logarray = <FF>; if($debug){&writelog(1,"DEBUG: Entered into readfile_rt: passed ($tag +1)($tag2)");} foreach(@logarray){ if(($_ =~ m/35=8/)&&($_ =~ m/$tag1/)){ if(($debug)&&($datadumperdebug)){&writelog(1,"DEBUG: readfile_rt: + found string $_");} printf "Found = $_\n"; } }
        But that returns loads of rows and not one row, and some of them don't even match
Re: File lines being treated as one.
by bobf (Monsignor) on Mar 03, 2006 at 21:44 UTC

    I asked a related question a while ago, and got many helpful replies that are also applicable to your question. Please see Newlines: reading files that were created on other platforms.

    In short, I chose to preprocess the input file to convert all newline characters to the current system's newline character:

    $file =~ s[(\015)?\012(?!\015)][\n]g; $file =~ s[(\012)?\015(?!\012)][\n]g;

    HTH

Re: File lines being treated as one.
by radiantmatrix (Parson) on Mar 03, 2006 at 15:30 UTC

    As others have pointed out, lines end differently on UNIX and Windows. What you want to do is ensure that your input record separator (stored in the Perl special variable <c>$/<c/> {see perlvar}) is set correctly for the type of file you wish to read.

    local $/ = "\r\n"; # read with Windows-style endings while (<FH>) { print "Found: $_"; }

    (Quick note: the line endings stay on the line unless you chomp them off.)

    There are other approaches if you don't know what line endings you will be dealing with. The easiest is to slurp the whole file and then split it yourself, though this is a bad idea for very large files.

    use File::Slurp; my $content = read_file('my_file.txt'); for ( split(/[\r\n]+/, $content) ) { print "Found: $_\n"; }

    This splits on any of \r, \n, or \r\n (or, incidentally, \n\r), taking care of Mac, Windows, or UNIX line endings. As a side effect, blank lines are skipped and all line endings are trimmed off. This may or may not be desirable.

    <-radiant.matrix->
    A collection of thoughts and links from the minds of geeks
    The Code that can be seen is not the true Code
    I haven't found a problem yet that can't be solved by a well-placed trebuchet