使用jq

时间:2015-11-05 20:33:51

标签: json bash sh jq

我试图在bash / shell脚本中使用jq <map>函数修改嵌​​套的JSON对象;与this blog entry类似的东西,但试图将这里的例子改编为嵌套对象。

要返回的返回JSON如下:

{
  "name": "vendor-module",
  "dependencies": {
    "abc": {
      "from": "abc@2.4.0",
      "resolved": "https://some.special.url",
      "version": "2.4.0"
    },
    "acme": {
      "from": "acme@1.2.3",
      "resolved": "<CHANGE_THIS>",
      "version": "1.2.3"
    }
  }
}

这将是我的尝试:

modules="`node -pe 'JSON.parse(process.argv[1]).dependencies.$dependency' \
  "$(cat $wrapped)"`"
version="1.2.3"
resolved="some_url"

cat OLD.json | 
  jq 'to_entries | 
       map(if .dependencies[0].$module[0].from == "$module@$version"
          then . + {"resolved"}={"$resolved"}
          else . 
          end
         ) | 
      from_entries' > NEW.json

显然这不起作用。当我运行脚本时,NEW.json被创建但没有修改或返回错误。如果我没有定位嵌套对象(例如"name": "vendor-module"),则脚本按预期工作。我相信有一种方法可以使用本机bash和jq来做到这一点。??任何帮助(适当的逃避)将不胜感激。

更新

Thnx在Charles Duffy's answer的帮助下,以及他使用sponge的建议,对我有用的解决方案是:

jq --arg mod "acme" --arg resolved "Some URL" \
   '.dependencies[$mod].resolved |= $resolved' \
   OLD.json | sponge OLD.json

2 个答案:

答案 0 :(得分:2)

如果您知道要更新的依赖项的名称,则可以将其编入索引。

$ jq --arg dep "$dep" --arg resolved "$resolved" \
    '.dependencies[$dep].resolved = $resolved' \
    OLD.json > NEW.json

否则,要根据名称(或其他属性)修改依赖项,请搜索依赖项并进行更新。

$ jq --arg version "$version" --arg resolved "$resolved" \
    '(.dependencies[] | select(.version == $version)).resolved = $resolved' \
    OLD.json > NEW.json

答案 1 :(得分:0)

对于您现有的样本数据,以下内容足够:

Select * from A_ as lcp
ConsumerID LowestAnnualCost
1               23
2               19
3               10
4               54
5               25

Select * from B_ as lacp
ConsumerID LowestAnnualCost
1               23
2               19
3               98
4               NULL
5               25

...过滤jq --arg mod "acme" \ --arg resolved "some_url" \ '.dependencies[$mod].resolved=$resolved' \ <in.json >out.json ,相反:

from