将JSON对象传递给jq参数

将JSON对象传递给jq参数,json,bash,parameter-passing,jq,data-processing,Json,Bash,Parameter Passing,Jq,Data Processing,数据样本-sample.json(完整样本:) 使用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' \

数据样本-sample.json(完整样本:)

使用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' \
   <<<'{}'
现在它只是以字符串的形式返回对象,我尝试了很多不同的方法来解决这个问题。我对使用JSON和jq还很陌生,但是根据我到目前为止读到的内容,解决方案可能不像我希望的那么简单

简单地说,为什么不将对象作为sample.json对象的值返回,我必须做什么才能使它工作

谢谢

致:切普纳

{
  "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不支持在中计算jq表达式 这将是您尝试工作所需的方式。你可以做一些 一种shell插值,但最好使用JSON路径, e、 g.您可以编写
    --arg value0“host”
    ,而不是
    --arg value0“host”
    ,等等。在下面的代码中,我使用了
    getpath/1

  • 无需在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"
    }
    
  • jq不支持在中计算jq表达式 这将是您尝试工作所需的方式。你可以做一些 一种shell插值,但最好使用JSON路径, e、 g.您可以编写
    --arg value0“host”
    ,而不是
    --arg value0“host”
    ,等等。在下面的代码中,我使用了
    getpath/1

  • 无需在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"
    }
    

    下面是一个使用@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查询语言——从设计上讲——提供了更大的灵活性。

    下面是一个使用@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查询语言——从设计上讲——提供了更大的灵活性。

    在回答补充问题(“to: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\u str
    周围的一对括号


    正如其他地方提到的,jq查询又是如此简单和直截了当,似乎怀疑参数化版本是否会提供任何优势

    关于补充问题(“致:切普纳”):

    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\u str
    周围的一对括号


    正如其他地方提到的,jq查询又是如此简单和直截了当,似乎怀疑参数化版本是否会提供任何优势

    为什么需要这些变量?只需使用
    jq'{Host:.http.Host,漏洞:.ops.vulns,IPS:.isp}'tmp.json
    @chepner当然可以,但在我看来,只要能够简单地调用不同的参数,就可以更简单地构造数据。最后,使用完整的数据集,我希望我的数据结构看起来像这样:(添加到帖子中)坦白地说,它所做的是我作为一个用户所期望和希望的。将数据作为代码进行评估通常是不好的做法(出于安全性和可预测性等原因),需要采取明确的步骤。也就是说,采用接受JSON列表并遍历该列表中元素命名(或编号)的元素的代码当然是可行的。我当然不希望有一个完整的计算器……因此,如果我写一个答案,它的输入/调用约定看起来更像:
    config='{“主机”:[“主机”],“漏洞”:[“选项”,“vulns”,0],“ISP”:[“ISP”]};jq--argjson config“$config”…”为什么需要变量?只需使用
    jq'{Host:.http.Host,漏洞:.ops.vulns,IPS:.isp}'tmp.json
    @chepner当然可以,但在我看来,只要能够简单地调用不同的参数,就可以更简单地构造数据。最后,使用完整的数据集,我希望我的数据结构看起来像这样:(添加到帖子中)坦白地说,它所做的是我作为一个用户所期望和希望的。将数据作为代码进行评估通常是不好的做法(出于安全性和可预测性等原因),需要采取明确的步骤。也就是说,采用接受JSON列表并遍历该列表中元素命名(或编号)的元素的代码当然是可行的。我当然不希望有一个完整的计算器……因此,如果我写一个答案,它的输入/调用约定看起来更像:
    config='{“主机”:[“主机”],“漏洞”:[“选项”,“vulns”,0],“ISP”:[“ISP”]};jq--argjson配置“$config”…”嘿。我本来想自己写
    getpath
    谢谢,所以我没有打100%的折扣。试图使用
    argjason
    etc,但没有意识到,这就是您在/getpath
    方法中声明
    path
    的方式。。对于将数据获取到上一个示例中的结构,您有什么建议吗?它有不同的数据,但是想法是一样的。我本来想自己写
    getpath
    谢谢,所以我不是100%o