如何编写一个高亮匹配的ngrep包装器?

2 投票
7 回答
1593 浏览
提问于 2025-04-11 09:34

我刚刚了解到一个很酷的程序叫做 ngrep,它可以让你轻松地捕捉到包含特定字符串的数据包。

不过,有一个问题就是在输出的内容中,找到匹配的部分可能会很困难。于是我想写一个包装脚本来高亮显示这些匹配的部分——可以使用ANSI转义序列来实现:

echo -e 'This is \e[31mRED\e[0m.'

我对Perl比较熟悉,但如果用Python或其他语言也没问题。最简单的方法可能是这样的:

while (<STDIN>) {
   s/$keyword/\e[31m$keyword\e[0m/g;
   print;
}

不过,这个方法并不好,因为ngrep在收到不匹配的数据包时会打印出井号(#),而且没有换行,而上面的代码会等到看到换行后才会显示这些井号。

有没有办法在不影响井号即时出现的情况下进行高亮显示呢?

7 个回答

3

你也可以通过ack来处理输出。使用 --passthru 这个选项会很有帮助。

4

这段话的意思是,这个方法似乎有效,至少在比较两个窗口的时候,一个窗口运行的是普通的ngrep命令(比如说ngrep whatever),而另一个窗口则是把这个命令的结果传递给下面的程序(也就是ngrep whatever | ngrephl target-string)。

#! /usr/bin/perl

use strict;
use warnings;

$| = 1; # autoflush on

my $keyword = shift or die "No pattern specified\n";
my $cache   = '';

while (read STDIN, my $ch, 1) {
    if ($ch eq '#') {
        $cache =~ s/($keyword)/\e[31m$1\e[0m/g;
        syswrite STDOUT, "$cache$ch";
        $cache = '';
    }
    else {
        $cache .= $ch;
    }
}
3

唉,算了。这实在是太麻烦了。直接拿到ngrep的源代码,然后让它把哈希标记打印到错误输出上,简单多了:

--- ngrep.c     2006-11-28 05:38:43.000000000 -0800
+++ ngrep.c.new 2008-10-17 16:28:29.000000000 -0700
@@ -687,8 +687,7 @@
     }

     if (quiet < 1) {
-        printf("#");
-        fflush(stdout);
+      fprintf (stderr, "#");
     }

     switch (ip_proto) {                 

然后,过滤就轻松多了:

while (<CMD>) {
  s/($keyword)/\e[93m$1\e[0m/g;
  print;
}

撰写回答