Получить последние N элементов для каждого элемента объекта JSON - PullRequest
1 голос
/ 01 октября 2019

Учитывая следующий объект JSON, используя jq, как получить последние два элемента для каждого элемента?

Я пытался найти решение с помощью jqplay.org, но нигде не получил,Хотя получение значений из объектов, имеющих согласованные имена ключей, довольно просто, я не могу разобраться с этим.

Ввод:

{
  "foo": {
    "abc": { "key1": "value1" }, 
    "bcd": { "key1": "value1" },
    "cde": { "key1": "value1" },
    "def": { "key1": "value1" }, 
    "efg": { "key1": "value1" },
    "fgh": { "key1": "value1" }
  }, 
  "bar": {
    "ghi": { "key1": "value1" }
  }, 
  "qux": {
    "hij": { "key1": "value1" }, 
    "ijk": { "key1": "value1" },
    "jkl": { "key1": "value1" },
    "klm": { "key1": "value1" }
  }
  /* ... */
}

Ожидаемый результат:

{
  "foo": {
    "efg": { "key1": "value1" },
    "fgh": { "key1": "value1" }
  }, 
  "bar": {
    "ghi": { "key1": "value1" }
  }, 
  "qux": {
    "jkl": { "key1": "value1" },
    "klm": { "key1": "value1" }
  }
  /* ... */
}

Ответы [ 3 ]

1 голос
/ 01 октября 2019

Один из вариантов - удалить все поля, кроме последнего N (2 здесь), используя delpaths. Вам необходимо преобразовать имена ключей в представления пути. Например:

map_values(delpaths(keys_unsorted[:-2] | map([.])))

См. Демонстрационную версию jqplay .

0 голосов
/ 03 октября 2019

вот альтернативное (то есть не-jq) решение запроса OP: запрос состоял в том, чтобы удалить все записи во всех итерациях второго уровня (из корня), кроме двух последних.

Использование jtc, то самый простой (и самый лаконичный) способ - пройти всех нежелательных записей и очистить их:

bash $ <input.json jtc -w[:][:-2] -p
{
   "bar": {
      "ghi": {
         "key1": "value1"
      }
   },
   "foo": {
      "efg": {
         "key1": "value1"
      },
      "fgh": {
         "key1": "value1"
      }
   },
   "qux": {
      "jkl": {
         "key1": "value1"
      },
      "klm": {
         "key1": "value1"
      }
   }
}

walk-path ([:][:-2]) здесь довольно тривиален:
- [:] будет выполнять итерацию по всем узлам JSON в верхней (корневой) итерируемой (то есть итерации по bar, foo, qux элементов)
- [:-2] будет выполнять итерацию для каждой итерированной (в предыдущем лексеме) итерации, начиная с первой до (но не включительно) второй от конца (например, объект foo)будет повторяться abc через def и т. д.).
Примечание: нотация выбора диапазона в jtc почти такая же, как в Python.

Тогда-p дает указание очистить все завершенные прогулки, фактически оставив исходную структуру JSON и те элементы, которыене гуляли - это облегчает запрос.

(PS. Я являюсь разработчиком jtc инструмента Unix для обработки JSON).

0 голосов
/ 01 октября 2019

Простое и эффективное решение:

map_values( to_entries[-2:] | from_entries)
...