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

This is turning into a rather strange issue. Whenever I try to execute this command:
grep -B 1 -i "Northbound to" file1 > file2 grep -B 1 -i "Southbound to" file1 >> file2
I get an error saying
grep: illegal option -- B Usage: grep -hblcnsviw pattern file . . . grep: illegal option -- B Usage: grep -hblcnsviw pattern file . . .
Is there another way of displaying one line before either or both matches? Obviously what I'm looking for is the interface that this is on. Below is a small portion of 'file1'. Thanks for any and all ideas.
interface POS2/1 bandwidth 155520 no ip address no ip directed-broadcast no ip proxy-arp load-interval 30 shutdown crc 16 ! interface POS2/2 description PL000000/00000000-O, NNI southbound To Somewhere fms 1111 +1111 no ip address no ip directed-broadcast no ip proxy-arp encapsulation frame-relay IETF no ip mroute-cache crc 16 frame-relay lmi-type cisco ! interface POS2/2.30 point-to-point description POS2/2.30 fr dlci=30. By VPNSC: Job Id# = 9999 ip vrf forwarding V1234:Customer ip address 192.168.254.2 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 30 IETF

Replies are listed 'Best First'.
Re: Print line before match
by toolic (Bishop) on Mar 04, 2010 at 14:57 UTC
    In Perl, the key is to keep a copy of the previous line:
    use strict; use warnings; my $prev; while (<DATA>) { print $prev if $prev and /Northbound to/i or /Southbound to/i; $prev = $_; } __DATA__ interface POS2/1 bandwidth 155520 no ip address no ip directed-broadcast no ip proxy-arp load-interval 30 shutdown crc 16 ! interface POS2/2 description PL000000/00000000-O, NNI southbound To Somewhere fms 1111 +1111 no ip address no ip directed-broadcast no ip proxy-arp encapsulation frame-relay IETF no ip mroute-cache crc 16 frame-relay lmi-type cisco ! interface POS2/2.30 point-to-point description POS2/2.30 fr dlci=30. By VPNSC: Job Id# = 9999 ip vrf forwarding V1234:Customer ip address 192.168.254.2 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 30 IETF
    Prints:
    interface POS2/2
      Perfect, works like a charm. Thank you so much.
      One more thing...now that I have this output (slightly modified) I need to go back thru a file and find all matches. Basically, I need to grab a line in one file, and find all lines in the second file that match, as well as several lines below. File 1:
      interface POS2/2. interface POS4/1.
      File 2:
      interface POS2/1 bandwidth 155520 no ip address no ip directed-broadcast no ip proxy-arp load-interval 30 shutdown crc 16 ! interface POS2/2 description PL99999/9999999999-O, NNI southbound To Somewhere no ip address no ip directed-broadcast no ip proxy-arp encapsulation frame-relay IETF no ip mroute-cache crc 16 frame-relay lmi-type cisco ! interface POS2/2.30 point-to-point description POS2/2.30 fr dlci=30. By VPNSC: Job Id# = 111 ip vrf forwarding ABC:ABCD ip address 192.168.254.2 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 30 IETF ! interface POS2/2.31 point-to-point description POS2/2.31 fr dlci=31. By VPNSC: Job Id# = 112 ip vrf forwarding ACD:FGEI ip address 192.168.254.6 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 31 IETF !
      What I'm trying to extract from file 2, based on file 1 is this:
      interface POS2/2.30 point-to-point description POS2/2.30 fr dlci=30. By VPNSC: Job Id# = 111 ip vrf forwarding ABC:ABCD ip address 192.168.254.2 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 30 IETF interface POS2/2.31 point-to-point description POS2/2.31 fr dlci=31. By VPNSC: Job Id# = 112 ip vrf forwarding ACD:FGEI ip address 192.168.254.6 255.255.255.252 no ip directed-broadcast snmp trap link-status no cdp enable frame-relay interface-dlci 31 IETF
      I have tried using the code below, but it doesn't work at all for me:
      open(OUTFILE, ">outfile"); open(MYINPUTFILE, "file2"); open(MYINPUTFILE1, "file1"); while (<MYINPUTFILE>) { my($line) = $_; my $line1 = <MYINPUTFILE1>; chomp($line1); print OUTFILE if /$line1/ .. /frame-relay/; } close(MYINPUTFILE); close(MYINPUTFILE1);
      I will have to make more modifications after that, but I already have most of that written. Any help is always appreciated.

        Problem is you're reading one line from file1 for every line in file2 (so you soon run out of lines in file1).

        I think you rather want nested loops, i.e. something along the lines of

        open F1, "file1" or die $!; while (my $find = <F1>) { chomp $find; open F2, "file2" or die $!; while (<F2>) { print if /$find/ .. /frame-relay/; } }

        P.S. sorry about the first reply... (it didn't look like you wanted to learn Perl).

Re: Print line before match
by almut (Canon) on Mar 04, 2010 at 14:48 UTC

    Maybe you should get a grep which supports the -B option... GNU grep does, and should compile on nearly any platform.