-1

I want to match the string which is followed by " ETN : " i.e., (name1/name2 ) first and after I match it, I want to print the first occurrence of it before the string "data reached"

ETN: name1/name2  

   abchsfk/jshflka/ZN                       (cellLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name1/name2/ZN                 (abcLVT)    

   data reached



   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name1/name2/ZN                  (abcLVT)

ETN: name3/name4  

   abchsfk/jshflka/ZN                       (cellLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name3/name4/ZN                 (fhLVT)    

   data reached



   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name3/name4/ZN                  (fhLVT)

Output :

name1/name2/ZN                  (abcLVT)

name3/name4/ZN                 (fhLVT)

CODE:

I tried to march the string first with ETN and tried to print it.

if ($line =~ m/ETN: /)

        { 
    my @names = split / /, $line;

    $a = $names[3];

        if ($line =~ m /$a  /)

        { 
            print " $line \n" ; 
        }       

    }
SKG
  • 55
  • 12

2 Answers2

1

Your code doesn't show the loop where you retrieve $line from the file but it looks like you're trying to use a nested approach, in which case you're missing another such loop. That would work if each record ends in "data reached", but that's not consistently present in your example data. However a nested loop isn't necessary in this case nor does it add to readability, so just use a single loop as shown below.

First, a few comments:

  • You don't need the m// for your regex as // will suffice since it's not a multi-line match.

  • You should use an ^ anchor not only for accuracy but speed.

  • You can retrieve the name from the regex without the split line you have by using the special match variables e.g. $1 as shown below.

  • I didn't use $line in my code below, just the assumed $_ var, which is common perl style. Since it's assumed, it wasn't written in the code.

  • If you don't chomp the line, you don't need to add a newline when printing.

Here's your code, with the input loop shown, modified to work. I used $name in two conditionals below, which is equivalent to checking if it is both defined and not empty.

my $name;
while (<$in>)
{
    if (/^ETN:\s+(\S+)/) { $name = $1 }
    elsif ( $name and /^\s+$name/) { print }
}  
$name or warn("No ETN records found\n");
Edward Kirton
  • 165
  • 1
  • 6
  • Thank you the explanation. I was trying to write the code, still learning. Your explanation is really useful. I will work on it. – SKG Sep 05 '15 at 07:22
-1

You can use a simple regex for this. Try the following code:

if ($inputstring =~ m/ENT:.*?($name1/$name2)ZN/) {
    print "$1\t$2"
}

$name1 and $name2 will be the strings to match. This will print:

name1 tab name2
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110