如何使用 JQ 对 JSON 进行字符串化

How to stringify JSON using JQ

我想使用 JQ 获取一个复杂的 JSON 对象,其中包含作为字符串嵌入的 JSON,然后将其全部转换为我可以轻松嵌入到其他 JSON 中的有效字符串对象。

例如,假设我有这个 json 对象:

{
  "region": "CA",
  "waf_rule_tags": "{\"RULEID:942100\":[\"application-multi\",\"language-multi\",\"platform-multi\",\"attack-sqli\",\"OWASP_CRS/WEB_ATTACK/SQL_INJECTION\",\"WASCTC/WASC-19\",\"OWASP_TOP_10/A1\",\"OWASP_AppSensor/CIE1\",\"PCI/6.5.2\"]}"
}

我需要将其全部转换为以下字符串:

"{\"region\": \"CA\",\"waf_rule_tags\": \"{\\"RULEID:942100\\":[\\"application-multi\\",\\"language-multi\\",\\"platform-multi\\",\\"attack-sqli\\",\\"OWASP_CRS/WEB_ATTACK/SQL_INJECTION\\",\\"WASCTC/WASC-19\\",\\"OWASP_TOP_10/A1\\",\\"OWASP_AppSensor/CIE1\\",\\"PCI/6.5.2\\"]}\"}"

这样我就可以获取此字符串并将其准确插入另一个 JSON 对象的 text 字段下以创建以下内容。

{
      "title": "12345-accesslogs",
      "text": "{\"region\": \"CA\",\"waf_rule_tags\": \"{\\"RULEID:942100\\":[\\"application-multi\\",\\"language-multi\\",\\"platform-multi\\",\\"attack-sqli\\",\\"OWASP_CRS/WEB_ATTACK/SQL_INJECTION\\",\\"WASCTC/WASC-19\\",\\"OWASP_TOP_10/A1\\",\\"OWASP_AppSensor/CIE1\\",\\"PCI/6.5.2\\"]}\"}",
      "priority": "normal",
      "tags": ["environment:test"],
      "alert_type": "info"
}

简而言之,tostring是你的朋友。

假设您的原始 JSON 对象位于名为 object.json 的文件中,而模板位于 template.json 中,您可以这样写:

jq --argfile object object.json '.text = ($object | tostring)' template.json

不用说,这个主题有很多变体,例如

jq -n 'input | input + {text: tostring}' \
   object.json template.json

或更紧凑,如果稍微更晦涩:

jq 'input + {text: tostring}' object.json template.json

我发现@peak 在他们自己的回答中的评论非常有用,我想把它作为一个单独的答案:

$ echo '{ "foo": [ "bar", "baz" ] }' | jq tostring
"{\"foo\":[\"bar\",\"baz\"]}"

对此的一种变体是使用 tostring 将 JSON 结构中的给定键字符串化,如下所示:

echo '{"a":1,"b":{"c":{"d":2},"e":3}}' | jq '.b.c=(.b.c|tostring)'

...目标路径 b.c 给出:

{
  "a": 1,
  "b": {
    "c": "{\"d\":2}",
    "e": 3
  }
}

(根据 A.H. 的回答,如果您希望字符串也为 json-string-encoded,则 tojson 可能代替 tostring 有用)

JQ 为此提供 tojsonfromjson 过滤器。

关于提出 tostring 的答案的注意事项:JQ 手册说 tojson:

The tojson builtin differs from tostring in that tostring returns strings unmodified, while tojson encodes strings as JSON strings.

所以我认为 tojson 总是正确的,但是 tostring 只有当你 only 使用 complex[=29 时才正确=] 个对象。