Bash Scripting - 搜索文件以查找搜索条件以上的行

时间:2014-08-15 17:21:10

标签: bash grep full-text-search

我有100个配置文件,每个10,000到20,000行。这些是硬件的配置文件。我需要搜索所有配置文件以找到"配置文件"与给定的证书名称相关联。有几种不同版本的硬件软件,因此配置文件有些不同。但是,配置文件名称始终高于证书。配置文件名称不一定包含证书名称。

配置文件名称示例:
    clientssl_www.profile证书
    clientssl_www.example.com证书

证书名称示例:
    www.example.com.crt

配置的示例部分:

profile clientssl clientssl_www.profile-cert {
   defaults from clientssl
   key "www.example.com.key"
   cert "www.example.com.crt"
   chain "Intermediate-bundle.crt"
   options {
      cipher server preference
      dont insert empty fragments
      no sslv2
   }
}

ltm profile client-ssl /Common/clientssl_www.example.com-cert {
    app-service none
    cert /Common/www.example.com.crt
    cert-key-chain {
        www.example.com_www.example.com {
            cert /Common/www.example.com.crt
            chain /Common/Intermediate-bundle.crt
            key /Common/www.example.com.key
        }
    }
    chain /Common/Intermediate-bundle.crt
    ciphers 
    key /Common/www.example.com.key
    options { dont-insert-empty-fragments cipher-server-preference no-sslv2 }
}

我无法逐行读取配置文件,因为有数百万行,而且只需要太长时间。 我可以使用以下内容找到 grep 的证书名称:

$ grep www.example.com *file.conf | egrep 'cert "|cert /Common'

这给了我这样的东西:

   cert "www.example.com.crt"
    cert /Common/www.example.com.crt
            cert /Common/www.example.com.crt

我需要找到'个人资料名称'这高于我搜索给定的证书名称。

有什么建议吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用-B的{​​{1}}选项,在这种情况下会很方便。来自grep man 页面:

grep

因此,模式匹配现在将是:

-B NUM, --before-context=NUM
      Print  NUM  lines of leading context before matching lines.  Places a line containing a group separator (--) between contiguous groups
      of matches.  With the -o or --only-matching option, this has no effect and a warning is given.

输出:

$ grep www.example.com *file.conf | egrep -B3 'cert "|cert /Common'

但是,您仍需要在包含profile clientssl clientssl_www.profile-cert { defaults from clientssl key "www.example.com.key" cert "www.example.com.crt" -- ltm profile client-ssl /Common/clientssl_www.example.com-cert { app-service none cert /Common/www.example.com.crt cert-key-chain { www.example.com_www.example.com { cert /Common/www.example.com.crt 的行中找出一些常见模式以将其单独输出。在您的示例中,进一步过滤它变得困难,因为在第一种情况下,配置文件名称profile name模式之前是三行,而在第二个示例中,它是{{之前的两行) 1}}模式。

我觉得更好的另一种方法是在cert "本身找到一些模式。如果所有配置文件名称都包含字符串cert /,或者如果它们具有profile name等模式,则以下模式匹配将执行您所需的操作:

profile

输出:

clientssl.*-cert

更好的是,如果你知道个人资料名称以clientssl_开头并以-cert结尾,那么

$ grep www.example.com *file.conf | egrep 'profile|clientssl.*-cert'

输出:

profile clientssl clientssl_www.profile-cert {
ltm profile client-ssl /Common/clientssl_www.example.com-cert {

答案 1 :(得分:0)

这可能很疯狂,但每当我看到符合Tcl语法规则的示例数据时,我都希望生成一个Tcl解决方案:

#!/usr/bin/env tclsh

proc unknown {cmdname args} {
    set data [lindex $args end]
    if {[set idx [lsearch -exact $data "cert"]] != -1 && [string match $::cert_pattern [lindex $data [incr idx]]]} {
        set idx [expr {$cmdname eq "profile" ? 1 : [lsearch -exact $args "profile"] + 2}]
        puts [lindex [split [lindex $args $idx] /] end]
    }
}

set cert_pattern "*[lindex $argv 0]*"
foreach file [lrange $argv 1 end] {
    source $file
}

然后

$ ./cert.tcl www.example.com file.conf 
file.conf
clientssl_www.profile-cert
clientssl_www.example.com-cert

除非有一种色调和呐喊,否则我很难解释它是如何运作的。