代码之家  ›  专栏  ›  技术社区  ›  raldi

如何围绕突出显示匹配项的ngrep编写包装?

  •  2
  • raldi  · 技术社区  · 16 年前

    我刚刚知道 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 回复  |  直到 16 年前
        1
  •  4
  •   dland    16 年前

    这似乎可以做到这一点,至少可以比较两个窗口,一个直接运行ngrep(例如ngrep whatever),另一个通过管道连接到以下程序(使用ngrep whatever_ngrephl目标字符串)。

    #! /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;
        }
    }
    
        2
  •  3
  •   raldi    16 年前

    啊,算了吧。这太痛苦了。将源代码发送给ngrep并使其将哈希标记打印到stderr要容易得多:

    --- 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;
    }
    
        3
  •  3
  •   Andy Lester    16 年前

    您还可以通过管道传输输出 ack . --passthru标志将有所帮助。

        4
  •  1
  •   Community CDub    8 年前

    如果你有答案就不应该太难了 this question .

    (基本上,一次读取一个字符,如果是哈希,则打印它。如果不是哈希,请保存字符以便稍后打印。)

        5
  •  0
  •   Alex Coventry    16 年前

    这在Python中很简单。

    #!/usr/bin/env python
    import sys, re
    
    keyword = 'RED'
    
    while 1:
        c = sys.stdin.read(1)
        if not c:
            break
        if c in '#\n':
            sys.stdout.write(c)
        else:
            sys.stdout.write(
                (c+sys.stdin.readline()).replace(
                keyword, '\x1b[31m%s\x1b[0m\r' % keyword))
    
        6
  •  0
  •   Tony    16 年前

    为什么不使用-q参数调用ngrep来消除散列标记呢?

        7
  •  -1
  •   Shlomi Fish    16 年前

    参见脚本 this post to Linux-IL where someone asked a similar question . 它是用Perl编写的,使用CPAN术语::ansiColor模块。