【问题标题】:Passing JSON objects to jq arguments将 JSON 对象传递给 jq 参数
【发布时间】:2018-04-26 20:32:01
【问题描述】:

数据样本 - sample.json(完整样本:https://pastebin.com/KFkVmc2M

    {
      "ip": 3301234701,
      "_shodan": {
        "options": {
          "referrer": "7ae15507-f5cc-4353-b72e-5cc0b1c34c5e"
        },
      },
      "hash": -1056085507,
      "os": null,
      "title": "WHM Login",
      "opts": {
        "vulns": ["!CVE-2014-0160"],
        "heartbleed": "2017/08/29 09:57:30 196.196.216.13:2087 - SAFE\
        }
      },
      "isp": "Fiber Grid Inc",
      "http": {
        "redirects": [],
        "title": "WHM Login",
        "robots": null,
        "favicon": null,
        "host": "196.196.216.13",
        "html":
}

使用 jq 的脚本,我希望它可以工作,但还没有找到其他解决方案。

   cat sample.json | jq \
   --arg key0   'Host' \
   --arg value0 '.host' \
   --arg key1   'Vulnerability' \
   --arg value1 '.opts.vulns[0]' \
   --arg key2   'ISP' \
   --arg value2 '.isp' \
   '. | .[$key0]= $value0 | .[$key1]=$value1 | .[$key2]=$value2' \
   <<<'{}'

我希望但没有得到的最​​终结果:

{
  "Host": "196.196.216.13",
  "Vulnerability": "!CVE-2014-0160",
  "ISP": "Fiber Grid Inc"
}

现在它只是将对象作为字符串返回,我尝试了很多不同的方法来解决这个问题。我对使用 JSON 和 jq 很陌生,但根据我目前所读到的内容,解决方案可能不像我希望的那么简单?

简单地说,为什么对象没有作为 sample.json 对象的值返回,我必须做什么才能使其工作?

谢谢!

收件人:chepner

{
  "196.196.216.13":[
  "AS63119",
  "Fiber Grid Inc",
  "2017-08-29T06:57:22.546423",
  "!CVE-2014-0160"
],
"196.196.216.14":[
  "AS63119",
  "Fiber Grid Inc",
  "2017-08-29T06:57:22.546423",
  "!CVE-2014-0160"
]
}

【问题讨论】:

  • 为什么需要变量?只需使用jq '{Host: .http.host, Vulnerability: .ops.vulns, IPS: .isp}' tmp.json
  • @chepner 当然,但在我看来,能够简单地调用不同的参数将允许一种更简单的方式来构建我的数据。最后有了完整的数据集,我希望我的数据结构看起来像这样:(添加到帖子中)
  • 坦率地说,它所做的正是我作为用户所期望和希望的。将数据评估为代码通常是不好的做法(出于安全性和可预测性等原因),并且应该需要采取明确的步骤。
  • 也就是说,采用接受 JSON 列表并向下遍历由该列表中的元素命名(或编号)的元素的代码当然是可行的。我当然不会期待一个完整的评估者。
  • ...所以,如果我要为此写一个答案,它的输入/调用约定看起来更像:config='{"Host": ["host"], "Vulnerability": ["opts", "vulns", 0], "ISP": ["isp"]}'; jq --argjson config "$config" '...' &lt;in.json

标签: json bash parameter-passing jq data-processing


【解决方案1】:

这是使用@CharlesDuffy 建议的方法的变体解决方案:

$ config='{"Host": ["http", "host"], 
           "Vulnerability": ["opts", "vulns", 0], 
           "ISP": ["isp"]}'
$ jq --argjson config "$config" '
   . as $in
   | $config
   | map_values( . as $p | $in | getpath($p) )' pastebin.json

输出:

{
  "Host": "196.196.216.13",
  "Vulnerability": "!CVE-2014-0160",
  "ISP": "Fiber Grid Inc"
}

这顺便强调了@chepner 的观点:$config 所需的维护和维护不亚于相应的 jq 查询所需的维护和维护,而 jq 查询语言——通过设计——提供了更大的灵活性。

【讨论】:

    【解决方案2】:

    回答补充问题(“致:chepner”):

    pastebin 数据不包含“196.196.216.14”,因此补充问题不清楚,但您可能希望从以下内容开始:

    jq '{(.ip_str): [.asn, .isp, .timestamp, opts.vulns[0] ]}' pastebin.json
    

    这会产生:

    {
      "196.196.216.13": [
        "AS63119",
        "Fiber Grid Inc",
        "2017-08-29T06:57:22.546423",
        "!CVE-2014-0160"
      ]
    }
    

    这里的重点是.ip_str周围的一对括号。

    正如在其他地方提到的,jq 查询再次如此简单明了,以至于参数化版本是否会提供任何优势似乎值得怀疑。

    【讨论】:

    • 感谢您,唯一的问题是它会在每个响应周围产生{},而不是像示例中那样产生整体结果。 , 也不是在数组末尾添加的,正确使用 {} 将创建一个有效的 JSON
    • @user3086917 - 在 jq 中创建对象数组很简单,但由于您似乎没有给出具体示例或具体要求,因此很难为您提供所需的具体细节.无论如何,根据已经讨论过的内容,我建议您坚持使用 jq 查询,而不是尝试将它们参数化。
    【解决方案3】:
    1. jq 不支持在 您尝试工作所需的方式。你可以做一些 一种shell插值,但最好使用JSON路径, 例如而不是--arg value0 .host,你可以写--arg value0 "host"等。在下面,我使用了getpath/1

    2. 不需要在 jq 过滤器前面加上 '. |'

    无论如何,假设 pastebin 的 JSON 内容在 pastebin.json 中,你可以这样写:

      jq \
       --arg key0        Host \
       --argjson value0  '["http","host"]' \
       --arg key1        Vulnerability \
       --argjson value1  '["opts", "vulns", 0]' \
       --arg key2        ISP \
       --argjson value2  '["isp"]' \
       '. as $in
        | {}
        | .[$key0] = ($in|getpath($value0))
        | .[$key1] = ($in|getpath($value1))
        | .[$key2] = ($in|getpath($value2))' \
       pastebin.json
    

    这会有结果:

    {
      "Host": "196.196.216.13",
      "Vulnerability": "!CVE-2014-0160",
      "ISP": "Fiber Grid Inc"
    }
    

    【讨论】:

    • 嘿。我期待自己完成编写getpath 的工作。 :)
    • 谢谢,所以我没有 100% 折扣。试图使用argjason 等,但没有意识到,这就是你声明pathin/getpath 方法的方式。你有什么技巧可以将数据获取到上一个示例中的结构?它有不同的数据,但想法是一样的。
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多