I'm sure I've done this before with sed, but I can't find it. I thought I might challege my sed skills and whip it up, but I got lazy and wrote it in perl (though I'm sure you could do this yourself if you wanted). Just make sure to escape your "start" and "end" arguments for use in regexes.
Example: cgrep.pl -s 'some_function(' -e ');' -f ./some_source
Caveat: Wouldn't work if you had wierd nesting, like: some_function( ... some_function( ... ); ... ); you'd just match: some_function( ... some_function( ... );
#!/usr/bin/perl -w
#Usage # cgrep.pl -s <start pattern> -e <end pattern> -f <input file>
use strict; use Getopt::Long;
my($start, $end, $file);
GetOptions( "start=s" => $start, "end=s" => $end, "file=s" => $file, );
die "All arguments are required" unless ($start && $end && $file);
if( defined( $file ) && -e $file ) { open( IN, $file ) || die "couldn't open file"; }
my @matches; my $matching; my $linecount = 0;
while( my $line = readline *IN) { $linecount++; if( $line =~ /($start.*)/ ) { $matching = "true"; push( @matches, $linecount . ": " . $1 . "\n" );
# in some cases our whole pattern will be in one line... if( $1 =~ /$end/){ $matching = "0"; } next; }
if( $matching ) { if( $line =~ /(.*$end)/ ) { push( @matches, $linecount . ": " . $1 . "\n" ); $matching = "0"; } else { push( @matches, $linecount . ": " . $line ); } } }
print @matches;