使用 jq 在文件中查找并替换 json

Find and replace json in a file using jq

我是 jq 的新手,需要以下方面的帮助...

本质上,我正在尝试使用 bash 脚本 "find and replace" 文件中的 json 块。

我有一个名为 docs.json 的文件,我在其中检索了一组文档条目:

{
    "number_of_docs": "1000",
    "docs": [{
    {
        "_id": "000001",
        "_rev": "0",
        "_content": "abcdefg"
    },
    {
        "_id": "000002",
        "_rev": "0",
        "_content": "hijklmn",
        "_attachments": {
            "image1.png": {
                "content_type": "image/png"
                ...
            }
        }
    },
    {
        "_id": "000003",
        "_rev": "0",
        "_content": "opqrstuv"
    }]
}

我正在尝试用存储在变量中的 json 的新块替换所有具有“_attachments”的文档条目(整个块,而不仅仅是键的值)名为 "doc":

{
    "_id": "000002_masked",
    "_rev": "0",
    "_content": "[Document content has been masked for confidentiality.]",
    "_attachments": {
        "confidential.png": {
            "content_type": "image/png"
            ...
        }
    }
}

我尝试在 bash 脚本中使用 jq 和 运行 做的事情是可能的吗?

提前感谢您的帮助和提示。

关键是 select 具有 _attachments 键的文档,然后用 |= 运算符替换它们。

jq --argjson new "$doc" '(.docs[]| select(has("_attachments"))) |= $new' docs.json

--argjson 用于将 $doc 的值作为原始 JSON 值传递到过滤器中。

如果您不能使用 --argjson,您可以使用 -s slurp 选项以及过滤器,例如

  .[0] as $new
| .[1]
| ( .docs[] | select(has("_attachments")) ) = $new

如果以上内容在 filter.jq 中,则您的新文档在 new.json 中并且您的数据包含您在 docs.json 中描述的单个对象,然后

jq -M -s -f filter.jq new.json docs.json

会产生

{
  "number_of_docs": "1000",
  "docs": [
    {
      "_id": "000001",
      "_rev": "0",
      "_content": "abcdefg"
    },
    {
      "_id": "000002_masked",
      "_rev": "0",
      "_content": "[Document content has been masked for confidentiality.]",
      "_attachments": {
        "confidential.png": {
          "content_type": "image/png"
        }
      }
    },
    {
      "_id": "000003",
      "_rev": "0",
      "_content": "opqrstuv"
    }
  ]
}

注意 - 我没有 jq-1.3,所以我只能用 jq-1.5 验证这一点,但我相信这应该适用于 jq-1.3