如何 JSON.stringify 将文件插入到 JSON 消息中?

How to JSON.stringify insert a file into a JSON message?

我在这里有一条 SNS JSON 消息:https://s.natalian.org/2016-12-15/sns-event.json

但是我需要使用 Message 字段作为 JSON 数据结构的有效负载。我如何快速插入一块 JSON 以便最终的 JSON 看起来像:https://s.natalian.org/2016-12-15/sns-event-stringified-message.json

"Message": "[{\"From\": \"foo\",\"To\": \"bar\"}]",

为了本示例,要插入的 file.json 具有以下内容:

[
  {
    "From": "foo",
    "To": "bar"
  }
]

我目前正在用 JSON.stringify 手动完成,大型结构容易出错。

将另一个文件作为参数文件读入,然后从该文件中分配新的消息值。您可以使用 tojson(或 @json)获得当前对象的字符串化版本。

$ jq --argfile file file.json '.Records[0].Sns.Message = ($file | tojson)' input.json

这里有一个稍微不同但也更通用的方法。

假设我们要为 "Message" 字段赋值,无论它出现在哪里(也不管它出现的频率如何),而不必担心细节。

为了完全通用地做到这一点,这里有一个函数,它接受一个字段名称(一个 JSON 字符串)和所需的值:

def setall(key; value):
  walk(if type == "object" and has(key) then .[key] = value else . end);

(如果您的 jq 没有 walk/1,它的定义在 jq 的 builtin.jq 中给出,如下所示。)

要解决原来的问题,要使用的过滤器是:

setall( "Message"; $file|tojson )

其中 $file 可以在命令行中定义如下:

$ jq --argfile file file.json -f setall.jq input.json

这里假设所有 jq 位都放在一个名为 setall.jq.

的文件中

walk/1

# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;