JQ:我如何通过jq更新json的值?

时间:2015-11-16 05:53:48

标签: json dictionary jq

我有一个像这样的json文件:

{"users":{"347793":"user1"}}
{"users":{"6560536":"user2"}}
{"users":{"6637901":"user3"}}
{"users":{"5850517":"user4"}}
{"users":{"2907509":"user5"}}
{"users":{"6611743":"user6"}}
{"users":{"6535592":"user7"}}
{"users":{"5586286":"user8"}}
{"users":{"2484439":"user9"}}
{"messages":{"id":"id1","owner":{"id":"347793","type":"user"},"otherUser":{"id":"6560536","type":"user"}}}
{"messages":{"id":"id2","owner":{"id":"6637901","type":"user"},"otherUser":{"id":"6560536","type":"user"}}}
{"messages":{"id":"id3","owner":{"id":"2907509","type":"user"},"otherUser":{"id":"2484439","type":"user"}}}
{"messages":{"id":"id4","owner":{"id":"347793","type":"user"},"otherUser":{"id":"2907509","type":"user"}}}
{"messages":{"id":"id5","owner":{"id":"5850517","type":"user"},"otherUser":{"id":"5850517","type":"user"}}}
{"messages":{"id":"id6","owner":{"id":"5586286","type":"user"},"otherUser":{"id":"347793","type":"user"}}}

我想得到这样的输出文件,将所有者的类型更改为用户名:

{"users":{"347793":"user1"}}
{"users":{"6560536":"user2"}}
{"users":{"6637901":"user3"}}
{"users":{"5850517":"user4"}}
{"users":{"2907509":"user5"}}
{"users":{"6611743":"user6"}}
{"users":{"6535592":"user7"}}
{"users":{"5586286":"user8"}}
{"users":{"2484439":"user9"}}
{"messages":{"id":"id1","owner":{"id":"347793","type":"user1"},"otherUser":{"id":"6560536","type":"user2"}}}
{"messages":{"id":"id2","owner":{"id":"6637901","type":"user3"},"otherUser":{"id":"6560536","type":"user2"}}}
{"messages":{"id":"id3","owner":{"id":"2907509","type":"user5"},"otherUser":{"id":"2484439","type":"user9"}}}
{"messages":{"id":"id4","owner":{"id":"347793","type":"user1"},"otherUser":{"id":"2907509","type":"user5"}}}
{"messages":{"id":"id5","owner":{"id":"5850517","type":"user4"},"otherUser":{"id":"5850517","type":"user4"}}}
{"messages":{"id":"id6","owner":{"id":"5586286","type":"user8"},"otherUser":{"id":"347793","type":"user10"}}}

我不知道这样做,我尝试了一些代码,但它不起作用。

jq -c '.messages[] as $message| $message.owner.type|=.users[]|select(.id==$message.owner.id).name'

2 个答案:

答案 0 :(得分:1)

如果"消息的数量"非常大,那么分别处理每一个可能会更好,以避免将它们全部读入内存。

无论如何,下面说明了如何使用jq读取一个文件来构建字典,以及如何逐行处理第二个文件。

假设我们已将JSON分区为两个文件(users.json和messages.json),并且以下行正在process.jq中:

# 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;

($users | map(.users) | add) as $dict
| walk(if type == "object" and .type == "user"
       then .type = $dict[.id]
       else .
       end)

(如果你的jq已经有walk / 1,那么它的定义可以省略。)

然后可以使用以下命令处理消息:

$ jq --slurpfile users users.json -f process.jq messages.json

答案 1 :(得分:0)

您的数据没有结构,如果您给它一些,它会更容易。

{ users: map(.users // empty), messages: map(.messages // empty) }

当你用这个文件粘贴时,它会给你这个:

{
  "users": [
    { "347793": "user1" },
    { "6560536": "user2" },
    { "6637901": "user3" },
    { "5850517": "user4" },
    { "2907509": "user5" },
    { "6611743": "user6" },
    { "6535592": "user7" },
    { "5586286": "user8" },
    { "2484439": "user9" }
  ],
  "messages": [
    {
      "id": "id1",
      "owner": { "id": "347793", "type": "user" },
      "otherUser": { "id": "6560536", "type": "user" }
    },
    {
      "id": "id2",
      "owner": { "id": "6637901", "type": "user" },
      "otherUser": { "id": "6560536", "type": "user" }
    },
    {
      "id": "id3",
      "owner": { "id": "2907509", "type": "user" },
      "otherUser": { "id": "2484439", "type": "user" }
    },
    {
      "id": "id4",
      "owner": { "id": "347793", "type": "user" },
      "otherUser": { "id": "2907509", "type": "user" }
    },
    {
      "id": "id5",
      "owner": { "id": "5850517", "type": "user" },
      "otherUser": { "id": "5850517", "type": "user" }
    },
    {
      "id": "id6",
      "owner": { "id": "5586286", "type": "user" },
      "otherUser": { "id": "347793", "type": "user" }
    }
  ]
}

然后进行更换应该更容易。

(.users | add) as $users
    | (.messages[].owner |= (.type = $users[.id]))
    | (.messages[].otherUser |= (.type = $users[.id]))

然后,如果出于某种原因你想要回到你的其他结构,那么它应该很容易(但我不推荐它)。

{ users: .users[] }, { messages: .messages[] }