【问题标题】:JQ:How can i update the value of json by jq?JQ:如何通过 jq 更新 json 的值?
【发布时间】:2015-11-16 05:53:47
【问题描述】:

我有一个这样的 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'

【问题讨论】:

  • 你尝试了什么代码?请向我们展示代码和问题,而不是说它不起作用。

标签: json dictionary jq


【解决方案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

【讨论】:

    【解决方案2】:

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

    { 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[] }
    

    【讨论】:

    • 很棒的答案!而不是为.owner.otherUser 重复相同的块,你可以做(.messages[] | .owner, .otherUser) |= (.type = $users[.id]) :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多