LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   complicated pattern matching with awk or sed... (http://www.linuxquestions.org/questions/linux-newbie-8/complicated-pattern-matching-with-awk-or-sed-675572/)

alirezan1 10-10-2008 05:56 PM

complicated pattern matching with awk or sed...
 
hi guys,

I want to do pattern matching with awk or sed but I don't know how. here's what I want:

I have a line number for a pattern that I have already found using grep, and I know a pattern like "---" that happens a few lines above that certain line number. I want to print out the chunk between "---" and that line number. But here's the catch. the pattern "---" can be between 1 and 20 lines above that line number and I don't know how many lines above ... Also, another catch is that, "---" can happen multiple times in the file but I want the "CLOSEST" to the line number. Here's an example:

Here's the file:

Quote:

---
aaa
bbb
ccc
ddd

---
aaaa
bbbb
cccc
dddd
eeee
ffff
gggg
hhhh

---
jjj
dsf
qqq
www
eee

I found the pattern say qqq to be on line 20. I want to find the first --- before pattern qqq (line 20) and I want to print the entire chunk from --- till the qqq pattern printed out.

Can someone help me out here please?
Thanks

matthewg42 10-10-2008 07:45 PM

Not sure if there's such an easy way with sed. It would be simple in awk, but I'm going to give you a little perl script to do it instead.
Code:

#!/usr/bin/perl

use strict;
use warnings;

my $buf = "";
my $p1 = shift || die "please specify two patterns\n";
my $p2 = shift || die "please specify two patterns\n";

my $p1_found = 0;
while(<>)
{
        if (/^$p1$/)  { $p1_found = 1; $buf = ""; next; }
        if (/^$p2$/)  { print $buf; $buf = ""; $p1_found = 0; next; }
        if ($p1_found) { $buf .= $_; }
}

Example invocation: say the program is in a file called test.pl, and the input data in a file called data:
Code:

chmod 755 test.pl
./test.pl --- gggg < data

If you want to include the lines with the two patterns, just remove the next from the first if statement, and swap the second and third if lines.


All times are GMT -5. The time now is 05:00 PM.