Как найти объект и показать значение и полный путь? - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть некоторый JSON (усеченный), который выводится из встроенного состояния здоровья Elasticsearch.

{
  "gl-system-events_1" : {
    "settings" : {
      "index" : {
        "refresh_interval" : "1s",
        "number_of_shards" : "4",
        "blocks" : {
          "read_only_allow_delete" : "true"
        },
    ...
    ...

Я пытаюсь найти каждый экземпляр "read_only_allow_delete". Эти экземпляры могут быть вложены на разных уровнях в JSON или в разные объекты. Я хотел бы показать полный путь и значение (как это):

gl-system-events_1.settings.index.block.read_only_allow_delete: true

Есть ли эквивалент grep для JSON? У меня есть эта команда.

jq '.. | objects | select(.read_only_allow_delete)'

, которая производит этот вывод (но я также хотел бы увидеть полный путь).

{
  "read_only_allow_delete": "false",
  "read_only": "false"
}
{
  "read_only_allow_delete": "true"
}
{
  "read_only_allow_delete": "true"
}
{
  "read_only_allow_delete": "true"
}
{
  "read_only_allow_delete": "true"
}
{
  "read_only_allow_delete": "false",
  "read_only": "false"
}
{
  "read_only_allow_delete": "false",
  "read_only": "false"
}
{
  "read_only_allow_delete": "true"
}
{
  "read_only_allow_delete": "false",
  "read_only": "false"
}

Буду признателен за любую помощь.

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

При потоковой передаче данных можно получить пары путь / значение последовательности. Затем вы можете фильтровать по путям.

$ jq <input.json --stream 'select(length == 2 and .[0][-1] == "read_only_allow_delete")'
0 голосов
/ 06 ноября 2019

Вот одно решение, которое создает поток массивов [$ path, $ value], где $ path - полный путь, показанный в виде массива, а $ value - соответствующее значение:

paths as $path
| getpath($path) as $v
| select($path[-1] == "read_only_allow_delete" )
| [$path, $v]

Для примера ввода первая пара будет:

[["gl-system-events_1","settings","index","blocks","read_only_allow_delete"],"true"]

Если вы действительно хотите получить неоднозначный вывод, просто добавьте:

| "\($path|join(".")): \($v)"
...