【问题标题】:Trying to iterate operations on a file with awk and sed尝试使用 awk 和 sed 对文件进行迭代操作
【发布时间】:2017-08-16 19:09:37
【问题描述】:

我有一行显示在文件中的漏洞一词之后出现严重性一词的次数

请不要笑得太厉害:

cat <file> | sed '1,/vulnerabilities/d' | grep -c '"severity": 4'

这将返回“严重性”计数:文件中有 4 个匹配项。我似乎无法在其他文件中迭代它。

我有 100 个左右的文件,格式为 bleeblah-082017。 bleeblah 可以是不同的长度和单词。我在如何轻松地从上面的一个文件中迭代以从每个文件中获取结果时遇到问题。

我通常会使用 awk 行来遍历列表,但我似乎找不到任何融合 awk 和 sed 的示例。

有人对如何在多个文件上执行上述任务并返回每个文件的结果有任何想法吗?

谢谢 戴维

我有一个包含大量条目的文件,例如:
{ “计数”:6,
"plugin_family": "杂项", “plugin_id”:7467253, "plugin_name": "废话", “严重性”:4, “severity_index”:1, “vuln_index”:13

我想提取时间“严重性”:4 出现在每个文件中的漏洞一词之后。输出将是 10

更多的输入文件。

  "notes": null,
    "remediations": {
        "num_cves": 20,
        "num_hosts": 6,
        "num_impacted_hosts": 2,
        "num_remediated_cves": 6,
        "remediations": [
            {
                "hosts": 2,
                "remediation": "Apache HTTP Server httpOnly Cookie Information Disclosure: Upgrade to Apache version 2.0.65 / 2.2.22 or later.",
                "value": "f950f3ddf554d7ea2bda868d54e2b639",
                "vulns": 4
            },
            {
                "hosts": 2,
                "remediation": "Oracle Application Express (Apex) CVE-2012-1708: Upgrade Application Express to at least version 4.1.1.",
                "value": "2c07a93fee3b201a9c380e59fa102ccc",
                "vulns": 2
            }
        ]
    },
    "vulnerabilities": [
        {
            "count": 6,
            "plugin_family": "Misc.",
            "plugin_id": 71049,
            "plugin_name": "SSH Weak MAC Algorithms Enabled",
            "severity": 1,
            "severity_index": 0,
            "vuln_index": 15
        },
        {
            "count": 6,
            "plugin_family": "Misc.",
            "plugin_id": 70658,
            "plugin_name": "SSH Server CBC Mode Ciphers Enabled",
            "severity": 1,
            "severity_index": 1,
            "vuln_index": 13
        },
        {
            "count": 2,
            "plugin_family": "Web Servers",
            "plugin_id": 64713,
            "plugin_name": "Oracle Application Express (Apex) CVE-2012-1708",
            "severity": 2,
            "severity_index": 2,
            "vuln_index": 12
        },

这些文件中的每一个都来自从我的扫描仪 API 中提取的漏洞扫描。本质上,严重性这个词在不同方面(主机、漏洞等)无处不在。我想从每个扫描文件中提取模式在漏洞一词之后出现的次数(每个文件中只出现一次)。开放使用 perl python 来实现这一点。过去只是更熟悉使用 shell 脚本来操作这些文本类型文件。

【问题讨论】:

  • 我真的不完全清楚你想要达到的目标,因为你的第一个陈述有点模棱两可。我可以建议您包含一个(小)示例输入文件和您期望的输出吗?
  • 我也不明白你的问题。该行是 JSON。您最好使用 Perl 或 Python 来解析(并可能过滤它)它。至少一个单行使其成为多行。您在谈论“遍历列表”-&lt;file&gt; 是否在每一行中都包含这些 JSON 对象?并且:“融合 awk 和 sed”您可以单独使用 awk 进行任何 sed 操作。显示一个包含单词“vulnerabilities”的示例&lt;file&gt;
  • 添加更多上下文输入行

标签: bash awk sed pattern-matching


【解决方案1】:

sedawk 解析.json 数据充满了潜在的陷阱。我建议使用jq 之类的格式感知工具来查询您想要的数据。在这种情况下,您可以执行类似的操作

jq '{(input_filename): [.vulnerabilities[].severity]|add}' *.json

这应该会产生类似的输出

{
  "bleeblah-201708.json": 4
}
{
  "bleeblah-201709.json": 11
}

【讨论】:

  • 哦等等,这不正确。再次检查问题。我已经想知道了
  • 我将您提供的示例 JSON 作为“更多的输入文件”,使其成为有效的 JSON(因为您只提供了一个摘录,它本身是无效的),并且上面的查询确实vulnerabilities 部分中 severity 值的每个文件的计数。您请求在“严重性:4”处进行统计,但您的示例数据不包含任何带有 severity:4 的值。使用正确的示例输入数据和正确的输出数据,可以调整 jq 命令以仅查询 severity:4匹配的那些。
【解决方案2】:

在命令行上使用jq 解析json。它是标准工具。使用像 sed 这样的基于文本的工具来解析 json 非常脆弱,因为它依赖于元素的顺序和 json 文档的格式,这并不能保证或者是 json 标准的一部分。

您正在寻找的是以下命令:

jq '[.vulnerabilities[]|select(.severity==4)]|length' file.json

如果要对多个文件运行它,请使用find

find FOLDER -name 'PATTERN.json' -print \
    -exec jq '[.vulnerabilities[]|select(.severity==4)]|length' {} +

【讨论】:

    【解决方案3】:

    我制作了以下两个示例文件,假设它们可以代表您所拥有的。注意“漏洞”之前和之后出现的搜索文本,之后出现的次数不同。 从您的代码中,我假设搜索字符串最多只能在一行中出现一次,这些行将被计算在内。

    blableh-082017:

     "severity" : 4 
      "severity" : 4 
    
     vulnerabilities
    
     "severity" : 4 
      "severity" : 4
    

    bleeblah-082017:

     "severity" : 4 
      "severity" : 4 
     vulnerabilities
    
     "severity" : 4 
      "severity" : 4 
       "severity" : 4 
    

    这是我的建议,除了 sed 和 grep 使用 find 之外,还使用 ​​sh 在-exec 内部实现所需的管道。

    find . -iname "*-082017"  -print -exec sh -c "sed  1,/vulnerabilities/d {} | grep -c '\"severity\" : 4'" \;
    

    输出(希望名称行和计数行都可以,否则另一个 sed 可以为您重新格式化):

    ./blableh-082017
    2
    ./bleeblah-082017
    3
    

    详情:

    • 使用 find 处理多个文件,并获取每个文件名到输出,
      尽管 seds 对此缺乏支持
    • 基本上使用您的代码通过 sed 进行剪切并通过 grep 进行计数
    • 将文件名作为参数提供给 sed,而不是通过来自 cat 的管道
    • -exec内使用sh实现管道
      (devnull 回复How to use pipe within -exec in find

    环境:

    • GNU sed 4.2.1 版
    • GNU bash,版本 3.1.23(1)-release (i686-pc-msys)
    • GNU grep 2.5.4
    • 查找 (GNU findutils) 4.4.2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多