简体   繁体   中英

Print the matched string using perl

I want to match the string which is followed by " ETN : " ie, (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" ; 
        }       

    }

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM