写了做跨行搜索的脚本,用Perl。我知道也可以在bash里用sed,但我认为用那的话灵活性就不如用Perl了,因为我还要给它扩展各种我需要的功能。
闲话少说,上代码!
[perl]
!/usr/bin/perl -w
Hacked by WANG Cong.
Copyright (C) 2008, WANG Cong
Usage
mgrep.pl -s -e [—nonum]
use strict;
use warnings;
use Getopt::Long;
my($start, $end, $file);
my $num = 1;
my $allow_nest = 0;
my $allow_recursion = 0;
my $allow_binary = 0;
GetOptions(
“start=s” => $start,
“end=s” => $end,
“nonum” => sub { $num = 0; },
“recursion” => sub { $allow_recursion = 1 },
“binary” => sub { $allow_binary = 1 }
“nest” => sub { $allow_nest = 1; }
);
$file = shift;
die “$start and $end options are both required. And so is the file name.”
unless ($start && $end && $file);
my $start_reg = eval {qr/$start/};
die “The start pattern is not correct!” if $@;
my $end_reg = eval {qr/$end/};
die “The end pattern is not correct!” if $@;
## sub
sub mgrep_file
{
my @matches;
my $matching;
my $added = 0;
my $linecount = 0;
my $file = shift;
open( IN, $file ) or return undef;
while( my $line = readline *IN)
{
$linecount++;
if( $line =~ /($start_reg.*)/ )
{
$matching = 1;
if(!$added){
push @matches, "==", $file, "==n";
$added = 1;
}
if ($num) {
push( @matches, $linecount . ": " . $1 . "n" );
}else{
push( @matches, $1 . "n" );
}
if( $1 =~ /$end_reg/){ $matching = 0; }
next;
}
if( $matching )
{
if( $line =~ /(.*$end_reg)/ )
{
if ($num){
push( @matches, $linecount . ": " . $1 . "n" );
}else{
push( @matches, $1 . "n" );
}
$matching = 0;
}
else
{
if ($num){
push( @matches, $linecount . ": " . $line );
}else{
push( @matches, $line);
}
}
}
}
close IN;
return @matches;
}
sub mgrep_dir
{
my $dir = shift;
my @file_list;
my @match_list = ();
my $ret;
my @lret;
opendir(IN_DIR, $dir) || return undef;
@file_list = grep { $_ ne '.' and $_ ne '..' } readdir IN_DIR;
if (@file_list){
for my $one (@file_list) {
my $fname = "$dir/$one";
if (-f $fname){
next if(!-T $fname && !$allow_binary);
$ret = mgrep_file($fname);
next unless @$ret;
push @match_list, @$ret;
}
if ($allow_recursion && -d $fname){
@lret = mgrep_dir($fname);
next unless @lret;
push @match_list, @lret;
}
}
}
closedir IN_DIR;
return @match_list;
}
##### main
while ($file)
{
my $ret;
my @list;
if (-f $file){
next if(!-T $file && !$allow_binary);
$ret = mgrep_file($file);
print @$ret;
}
elsif (-d $file){
@list = mgrep_dir($file);
print @list;
}else{
die "$file is not existed!";
}
$file = shift;
}
[/perl]