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

This node falls below the community's threshold of quality. You may see it by logging in.
  • Comment on Concatenating lines found between two words

Replies are listed 'Best First'.
Re: Concatenating lines found between two words
by danger (Priest) on Feb 22, 2001 at 03:22 UTC

    Your failure to specify exactly what you mean (are the words on lines by themselves as delimiting lines? can they be anywhere? do you want to include the delimiting words/lines?) means I can freely assume you meant the following case: The two words are on lines by themselves and you want to include them (and for the present example, the words are START and STOP), and we'll read whatever file was passed on the command line:

    #!/usr/bin/perl -w use strict; my $string = ''; while(<>){ $string .= $_ if /^START$/ .. /^STOP$/; } print $string; __END__

    If your specs are different you'll have to adjust accordingly (ie, you can strip off the delimiting words easily enough, but if your file has multiple cases of such target regions, you'll get them all in a single string with the above).

Re: Concatenating lines found between two words
by OeufMayo (Curate) on Feb 22, 2001 at 03:08 UTC

    Welcome to the Monestary ploaiza.

    Here's an approach to your problem, but since you haven't clearly stated what your problem was (with example code, for instance), it might be a complete miss). And moreover it is a quick and dirty hack

    open (O, "rules.txt") or die "$!"; my ($wanted_lines); { local $/ = undef; # 'Slurp' mode on my $whole_file = <O>; close O; $whole_file =~ /FirstWord(.+?)LastWord/s; $wanted_lines = $1; } print $wanted_lines

    Update

    danger solution is really neat! forget mine!

    Though, while looking at your code, one can see it is not really 'perlish'

    Here are a few point that could improve your perl coding style.

    • ($_ =~ /^Lot Code/)
      can be replaced by
      (/^Lot Code/)
      as the match is against the $_ anyway.
    • your open is surely placed in the wrong spot as it will be called for each lines of your input file. Place it just after the '}'
    • for ($j=0; $j < $i; $j++)
      You can use the '..' operator to make things clea(n|r)er:
      for (0 .. $i)
    • You could perhaps use a Hash of Hashes instead of a zillion of arrays, with the key being $i:
      my %datas = ( 
         1 => {subject => 'foo', failed => 'bar',},
         2 => {subject => 'baz', failed => 'too',},
      );
      
    <kbd>--
    PerlMonger::Paris(http => 'paris.pm.org');</kbd>
Re: Concatenating lines found between two words
by clintp (Curate) on Feb 22, 2001 at 03:06 UTC
    1. In a string? s/(word1)\n(word2)/$1 $2/g;
    2. In an array? Search for lines starting/ending with the combination you want and splice them up. Or just re-use the above:
      @array=<FH>; $_=join('', @array); s/(word1)\n(word2)/$1 $2/g; @array=split(/\n/, $_);
    3. In a file? See #2
      I have a text file which I am parsing and it looks like this:
      Subject: Lab Test Log #1946 Date: Thu, 1 Jun 2000 10:56:15 -0500 (CDT) From: JUDY F <judyf@elgiloy.com> To: HAMPSHIRE - KUR <hampsc@combmet.com> FAILED HV HRD. I'LL CONT. TEST @ SHERRY'S CLAY, UNLESS I HEAR FFM. YOU. THANKS JUDY ELP - HAMPSHIRE(21) 06-01-00 + 10:54:34 JUDY F TERM # 171 LAB TEST LOG - LAB #1946 P +AGE # 1 ---------------------------------------------------------------------- +---------- Date In 05-30-00 1:00pm In Initials JF Lab Test Type Final Tag # 116014 Customer In Comments RTR 10342 COIL B ---------------------------------------------------------------------- +---------- Status Non-Conforming Date Out 06-01-00 10:52am Out Initials JF Lot Code H88231C Out Comments @.0075 T 102538 Y 39121 E 70% HRD.83 HRB (*159HV1KG)7RA B 3.48 DL .25 @ S.L.PER SUS. IGA /DOES NOT MEET WARD HV HRD. ---------------------------------------------------------------------- +---------- ** ORDERS ** ---------------------------------------------------------------------- +---------- 21 12136-1 COMBINED METALS OF CHICAGO
      I have been able to parse all the information that I want, but I need to get the lines that are between: Out Comments and ---- and I need to concatenate them into a string. In my code I have this...
      #!/bin/perl $delimiter = ","; $i=0; while(<>) { chomp; ....(parsing of other info) ... if ($_ =~ /^Lot Code/){ @lotCode[$i] = $_; @lotCode[$i]=~ s/^Lot Code(\s+)(\w+)/$2/e; $i++; } open OUTPUT, ">>data.txt"; } for ($j=0; $j < $i; $j++) { print OUTPUT "@subject[$j];@failed[$j];@monthi[$j]/@dayi[$j]/@yeari[ +$j];@routerval[$j];" . "@tag[$j];@montho[$j]/@dayo[$j]/@yearo[$j];@lotCode[$j];@comme +ntso[$j]\n"; print "@subject[$j];@failed[$j];@monthi[$j]/@dayi[$j]/@yeari[$j];@ro +uterval[$j];" . "@tag[$j];@montho[$j]/@dayo[$j]/@yearo[$j];@lotCode[$j];@comme +ntso[$j]\n"; }
      I hope these is clear enough to help me
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Concatenating lines found between two words
by merlyn (Sage) on Feb 22, 2001 at 03:00 UTC
    Depends on how you will know when you see the words. Do you know them by line number? by regex? Are they on separate lines? What if they are on the same line?

    -- Randal L. Schwartz, Perl hacker