使用sub()函数有条件地更改jq中的JSON值

时间:2019-06-04 10:41:10

标签: json shell jq

我需要更改JSON数据中的某些值,并希望将其包括在已经存在的shell脚本中。我正在尝试使用jq这样做,并且需要“ sub()”函数来截取一部分字符串值。

使用此命令行:

jq '._meta[][].ansible_ssh_pass | sub(" .*" ; "")'

使用下面的数据将正确替换该值(切断数据中的所有内容,包括第一个空格),但只会打印出该值,而不是完整的JSON结构。

以下是示例JSON数据:

{_meta": {
    "hostvars": {
      "10.1.1.3": {
        "hostname": "core-gw1",
        "ansible_user": "",
        "ansible_ssh_pass": "test123 / ena: test2",
        "configsicherung": "true",
        "os": "ios",
        "managementpaket": ""
      }
    }
}}

输出应如下所示:

{"_meta": {
    "hostvars": {
      "10.1.1.3": {
        "hostname": "core-gw1",
        "ansible_user": "",
        "ansible_ssh_pass": "test123",
        "configsicherung": "true",
        "os": "ios",
        "managementpaket": ""
      }
    }
}}

我假设我必须添加某种基于“ if ... then”的参数,但是还无法获得jq的理解;)Manual有点粗略,我无法找到任何可以使我与需要做的事情相匹配的示例...

2 个答案:

答案 0 :(得分:0)

好,像往常一样...发布公开问题后,您便可以自己找到解决方案...;)

这个jq通话可以满足我的需求

jq '. ._meta.hostvars[].ansible_ssh_pass |= sub(" .*";"" )'

答案 1 :(得分:0)

除了您的考虑之外,还有一种基于步行路径Unix实用程序 jtc 的替代解决方案:

bash $ <file.json jtc -w'<ansible_ssh_pass>l' -u'[ansible_ssh_pass]:<^[^ ]*>R' -T'"{$0}"'
{
   "_meta": {
      "hostvars": {
         "10.1.1.3": {
            "ansible_ssh_pass": "test123",
            "ansible_user": "",
            "configsicherung": "true",
            "hostname": "core-gw1",
            "managementpaket": "",
            "os": "ios"
         }
      }
   }
}
bash $ 

这是一个简短的解释:

  • -w指向json中要应用更新(-u)的位置:<ansible_ssh_pass>l将递归搜索标签的首次出现。
  • -u从何处获取更新的源[ansible_ssh_pass]:<^[^ ]*>R':将搜索范围为标签^[^ ]*的RE字符串匹配ansible_ssh_pass
  • -T模板将在应用upate {$0}之前进行插值,将对匹配的RE进行插值(除字符串开头的空格以外的所有字符)

PS>披露:我是jtc-用于JSON操作的shell cli工具的创建者