2015-11-16 4 views
1

У меня есть JSON-файл, как это:JQ: Как я могу обновить значение json jq?

{"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' 
+0

Какой код вы попробовать? Пожалуйста, покажите нам код и проблему, вместо того, чтобы заявить, что она не работает. – FelisCatus

ответ

1

Ваши данные не имеют структуры, вам будет легче, если вы его немного.

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

Удивительный ответ! Вместо повторения одного и того же блока для '.owner' и' .otherUser' вы можете делать '(.messages [] | .owner, .otherUser) | = (.type = $ users [.id])' :) –

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 уже ходить/1, то его определение может быть опущен)

Тогда следующая команда может быть использована для обработки сообщений:.

$ jq --slurpfile users users.json -f process.jq messages.json 
Смежные вопросы