regexperl

Print the matched string using perl


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" ; 
        }       

    }

Solution

  • 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:

    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");