文件搜索和邻近搜索

时间:2017-01-18 16:04:48

标签: perl awk sed grep ag

我一直在关注grep a file, but show several surrounding lines?

我正在使用bash终端,寻找

的文件
  • 任何一行都有pathredirect

  • 附近一行有flash,距离第一行

  • 五行内

这可能与grep,ag,Perl,sed或你们知道的任何工具有关吗?

3 个答案:

答案 0 :(得分:1)

更简单的过滤器是带有“闪光灯”的过滤器。首先执行此操作也很好,以便在匹配文件的子集中完成更昂贵的模式匹配。

为此,请说:

grep -RH -C 5 "text" *

这将以递归方式(-R)查找模式“text”并在发生这种情况时打印文件名(-H)。此外,它将打印周围的5行(-C 5)。如果您愿意,只需使用变量更改5

然后是时候用awk检查两个模式:

awk '/pattern1/ && /pattern2/ {print FILENAME}' file

这对awk is quite good on multiple patterns matching非常有用。

由于我们没有文件名,只有filename:flash等表格上的流,我们可以有一个基本的Bash循环来处理来自grep的结果:

while IFS=":" read -r filename data;
do
    awk -v f="$filename" '/path/ && /redirect/ {print f}' <<< "$data"
done < <(grep -RH -C5 "text" *)

答案 1 :(得分:1)

ack -A6 -B4 'path.*redirect|redirect.*path' FILES | grep flash

输出包含模式flash之前的4行中的模式FILES或包含模式pathredirect的行后6行的行包含flash的行的文件名和行号。

如果没有ack命令(或egrep命令(也可以),您可以将其改为两个grep命令

(grep -A6 -B4 'path.*redirect' FILES ; grep -A6 -B4 'redirect.*path' FILES) |
    grep flash

答案 2 :(得分:0)

这比看起来要复杂得多,因为你正在寻找近似的单词。

所以我可能会解决这个问题:

#!/usr/bin/env perl

use strict;
use warnings;

my $buffer_limit = 5; # +/- 5

my @buffer; 

my $first_flag;
my $second_flag; 

#iterate stdin or files specified on command line
while ( my $line = <> ) {

   #test first condition
   if ( $line =~ m/path/ and $line =~ m/redirect/ ) { $first_flag++; };
   #test second condition
   if ( $line =~ m/flash/ ) { $second_flag++; };

   #if either is true - match has been seen recently. 
   #save the line in the buffer. 
   if ( $first_flag or $second_flag ) { 
         push @buffer, $line
   }
   #if both are true, we print (and flush the buffer)
   if ( $first_flag and $second_flag ) { 
       print "Match found up to line $.:\n";
       print @buffer;
       @buffer = ();
       $first_flag = 0;
       $second_flag = 0; 
   }
   #exceeding limit means that both matches haven't been seen in proximity. 
   if ( @buffer > $buffer_limit ) { 
      @buffer = ();
      $first_flag = 0;
      $second_flag = 0;
   }
}

我们使用滚动的5行缓冲区。当我们击中一个或其他'匹配'时我们开始捕捉,如果我们击中第二场比赛,我们打印/冲洗。如果超过5行,则清空缓冲区。