jq извлекает одно поддерево из огромного (10 ГБ) файла JSON с помощью потоковой передачи - PullRequest
0 голосов
/ 06 марта 2019

У меня есть дамп базы данных, который состоит из одного огромного дерева JSON. Я хочу извлечь конкретное поддерево, которое будет намного меньше остальных, с известным конкретным ключом.

{ "key1": { subtree1... }, "key2": { subtree2... }, ... }

Как мне извлечь subtreeN с потоковой передачей jq?

1 Ответ

2 голосов
/ 06 марта 2019

В дальнейшем мы будем предполагать, что ключ $ содержит интересующий ключ.

Ключ к эффективности здесь заключается в том, чтобы завершить обработку потока, созданного параметром --stream, для завершения обработки $.ключ ключ.Для этого мы можем определить вспомогательную функцию следующим образом.Обратите внимание, что он использует inputs, и, следовательно, при вызове jq должен использоваться параметр командной строки -n.

# break out early
def filter($key):
  label $out
  | foreach inputs as $in ( null;
      if . == null
      then if $in[0][0] == $key then $in
           else empty
           end
      elif $in[0][0] != $key then break $out
      else $in
      end;
      select(length==2) );

Восстановление желаемой пары ключ-значение теперь можно выполнить следующим образом:

reduce filter($key) as $in ({};
  setpath($in[0]; $in[1]) )

Пример input.json

{
  "key1": {
    "subtree1": {
    "a": {"aa":[1,2,3]}
    }
  },
  "key2": {
    "subtree2": {
        "b1":  {"bb":[11,12,13]},
        "b2":  {"bb":[11,12,13]}
    }
  },
  "key3": {
    "subtree3": {
      "c":  {"cc":[21,22,23]}
    }
  }
}

Иллюстрация

jq -n -c --arg key "key2" --stream -f extract.jq input.json

Выход

{"key2":{"subtree2":{"b1":{"bb":[11,12,13]},"b2":{"bb":[11,12,13]}}}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...