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

Hi, I have a file where each line consists of 80 characters, then a newline character. I need to reformat it based on occurrences of the '#' character.
open(OUT,">$outfile"); open(F1, "<$infile") or die "Could not open $infile for reading!\n"; $/ = "#"; while (<F1>) { print OUT "$_\n"; }
The new file is correct that a new line begins for every '#' but how can I make it skip the newline characters so these lines are concatonated till the next '#'? (I hope that makes sense) (ASIDE: Is there a way to specify different line delimiters for different files using this notation when reading each file reading line by line simultaneously);
while ($line1 =<F1> || $line2= <F2>){ foo($line1,$line2); }

Replies are listed 'Best First'.
Re: skip newline charater when reading
by moritz (Cardinal) on Jan 13, 2009 at 10:46 UTC
    Remove all newlines in your strings:
    while (<F1>) { s/[\n\r]//g print OUT "$_\n"; }

    Something like that?

      Thanks that did it!
        When you mentioned that you wanted these "lines" to be "concatenated", what's the delimiter? In other words, what do you want to join them with?

        The trick is to translate all embedded "\n" to the delimiter of your choice. If the delimiter is a single character, you don't really need to use a full-on s///.

        If you wanted the delimiter as nothing:
          s/[\n\r]//g; # suggested by moritz tr/\n\r//d; # does the same

        If you wanted the lines to be joined by horizontal space:
Re: skip newline charater when reading
by JavaFan (Canon) on Jan 13, 2009 at 11:09 UTC
    while ($line1 =<F1> || $line2= <F2>){ foo($line1,$line2); }
    That's not going to do what you want. It reads from F1; if successful, it assigns that to $line2 and leaves $line2 and F2 as is. If reading from F1 fails (for instance, at the eof), it reads from F2, assigns that to both $line2 and $line1.

    It may be that you want:

    while (defined ($line1 = <F1>) and defined ($line2 = <F2>)) { ... }
Re: skip newline charater when reading
by gone2015 (Deacon) on Jan 13, 2009 at 11:56 UTC

    To do what I think you want from:

    while ($line1 =<F1> || $line2= <F2>){ foo($line1,$line2); }
    I suggest something along the lines of (i.e. untested):
    local $/ ; while (1) { $/ = "#" ; my $line1 = <F1> ; $/ = "?" ; my $line2 = <F2> ; last if (!defined($line1) && !defined($line2)) ; foo($line1, $line2) ; } ;
    Noting that if the files are different lengths, either $line1 or $line2 may be undefined when passed to foo. Stopping as soon as the shorter hits eof is a straightforward modification -- throwing an error if the two files are supposed to be the same length as necessary.

Re: skip newline charater when reading
by svenXY (Deacon) on Jan 13, 2009 at 10:41 UTC
    Hi,
    open(OUT,">$outfile"); open(F1, "<$infile") or die "Could not open $infile for reading!\n"; $/ = "#"; while (<F1>) { chomp; # <--- remove trailing newline character print OUT "$_\n"; }
    should do the trick
    Regards,
    svenXY
      open(OUT,">$outfile"); open(F1, "<$infile") or die "Could not open $infile for reading!\n";

      I realize that this is just an example snippet, but.... verbally fail if $infile won't open, and silently fail if the output file can't be opened? Also, have a look at the first paragraph or two of chomp and how it reacts to changes to $/. You're not removing the trailing newline characters.


      Dave

      chomp will try to remove the input record separator $/.

      $_ may have embedded "\n". The chomp approach does not deal with this issue.
      Thanks but doesn't that just remove the last character of the line that is read, this just deleted my '#' characters, leaving the newline characters.