?
Solved

Parse lines in a large text file

Posted on 2010-11-19
12
Medium Priority
?
545 Views
Last Modified: 2013-11-05
My file looks like this:

P1ACC01
interface g1/1
interface g1/2
interface g1/3
switchport mode trunk
interface g1/4
interface g1/5
switchport mode trunk
P1RLM01
interface g1/1
interface g1/2
interface g1/3
switchport mode trunk
interface g1/4
switchport mode trunk
interface g1/5
switchport mode trunk
interface g1/6

and on and on

The lines beginning "P1" are hostnames and will always start with P1. If an "interface" line is followed by a "switchport mode trunk" line, then I need to capture that for each host. If an interface line is followed by another interface line (meaning that it isn't a 'trunk' line) then I don't want to capture it.

So, I would like the output for a script run against the data lines above to look like:

P1ACC01
interface g1/3
switchport mode trunk
interface g1/5
switchport mode trunk
P1RLM01
interface g1/3
switchport mode trunk
interface g1/4
switchport mode trunk
interface g1/5
switchport mode trunk

I am basically trying to produce a report of the interfaces that are configured as trunks on each host.

Here's what I have so far (feel free to laugh, it's ok) and it doesn't work.

open (FILE, "</work/projects/interfaces.txt");
while ($line =<FILE>)
 {
   if ($line =~ m/^P1.*/)
     {
        $host=$line;
     }      
   $nextline = <FILE>;
   if ($nextline = /.interface./)
     {
             $line1=$nextline;
      $nextline1 = <FILE>;
      if ($nextline1 = /.trunk./)
        {
           printf "$host, $line, $line1\n";
                        }
      }
}

In fact, this produces nothing.

Thanks for your help.

Steve

0
Comment
Question by:SteveJ
  • 5
  • 5
  • 2
12 Comments
 
LVL 10

Expert Comment

by:jeromee
ID: 34177458
This seems to work:
perl -ne'print if/^P1/; print "$p$_" if/switchport mode trunk/; $p=$_' your_big_file
0
 
LVL 85

Expert Comment

by:ozo
ID: 34177535
perl -pe'BEGIN{$/="trunk"}s#(interface.*\n)+(?!.*$/)##' /work/projects/interfaces.txt
0
 
LVL 16

Author Comment

by:SteveJ
ID: 34177800
Thanks to you both . . . .honestly  . . . for responding so quickly on a Friday night. But I'm lost:

jeromee . . . your code produced:

Can't find string terminator "'" anywhere before EOF at -e line 1.

ozo  . . . your code produced:

P1ACC01
interface g1/1
interface g1/2
interface g1/3
switchport mode trunk
interface g1/4
interface g1/5
switchport mode trunk
P1RLM01
interface g1/1
interface g1/2
interface g1/3
switchport mode trunk
interface g1/4
switchport mode trunk
interface g1/5
switchport mode trunk
interface g1/6

I downloaded Active Perl 5.12 . . . no luck.

Thanks again,
Steve
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 10

Accepted Solution

by:
jeromee earned 1400 total points
ID: 34177853
Darn Windows!
I did it under UNIX.
Try this then:
    perl -ne "print if/^P1/; print qq($p$_) if/switchport mode trunk/; $p=$_;" your_big_file

0
 
LVL 85

Assisted Solution

by:ozo
ozo earned 600 total points
ID: 34177856
from a dos shell, you could quote it as
 perl -pe"BEGIN{$/='trunk'}s#(interface.*\n)+(?!.*$/)##" /work/projects/interfaces.txt
0
 
LVL 16

Author Closing Comment

by:SteveJ
ID: 34178483
Thanks jeromee and ozo . . .
0
 
LVL 10

Expert Comment

by:jeromee
ID: 34178519
Glad to help!
0
 
LVL 16

Author Comment

by:SteveJ
ID: 34188408
jeromee or ozo  . . .  could you please annotate your scirpts? I would be happy to open another question and give you points for the annotation.

Thanks
SteveJ
0
 
LVL 10

Expert Comment

by:jeromee
ID: 34190832
Here you go:
perl -ne "print if/^P1/; print qq($p$_) if/switchport mode trunk/; $p=$_;" your_big_file

-ne : open the file(s) passed as arguments (in this case your_big_file) and apply the following code to every line
print if/^P1/; : print the line if it starts (note the ^) with the string P1
print qq($p$_) if/switchport mode trunk/; : if the line contains the string "switchport mode trunk", print the previous line ($p) and the current line ($_). Note the qq($stuff) notation which is equivalent to "$stuff). qq() was used here because the one-line code was already delimited by "".
$p=$_ : save the value of the current line to be used as previous line when processing the next line
your_big_file : file to be processed
0
 
LVL 16

Author Comment

by:SteveJ
ID: 34191541
Thanks jeromee!! Turns out the big_file had a lot more garbage in it than I anticipated and I'm having to cobble a little more together to get the result that I wanted. The difficulty for me is reading a line, then reading another line . . . then reading a third line and handling the first line based on what's in the second or third line.

Thanks

Steve
0
 
LVL 10

Expert Comment

by:jeromee
ID: 34192704
Create another question with the details and we'll take a look at it.
0
 
LVL 16

Author Comment

by:SteveJ
ID: 34197223
Thanks jeromee.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
Progress
Starting up a Project

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question