jq для фильтрации элементов внутреннего массива, но возвращает все JSON - PullRequest
0 голосов
/ 10 июля 2020

TL; DR

Как я могу вернуть все JSON после фильтрации элементов внутреннего массива ключа верхнего уровня?

Подробное объяснение

У меня есть JSON с описанием базы данных изображений COCO, и он отформатирован следующим образом (нерелевантные элементы усечены как ...).

{
  "info": {
    "description": "COCO 2017 Dataset",
    ...
  },
  "licenses": [
    {
      "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/",
      ...
    },
    ...
  ],
  "images": [
    {
      "license": 4,
      ...
    },
  "annotations": [
    {
      "segmentation": [
        [
          510.66,
          ...
        ]
      ],
      "area": 702.1057499999998,
      "iscrowd": 0,
      "image_id": 289343,
      "bbox": [
        473.07,
        395.93,
        38.65,
        28.67
      ],
      "category_id": 18,
      "id": 1768
    },
  "categories": [
    {
      "supercategory": "person",
      ...
    },
  ]
}

Мне нужно отфильтровать annotations где category_id имеет одно из нескольких значений, например 1, 2.

Я могу успешно отфильтровать такие category_id s с помощью

jq -C ' .annotations[] | select( .category_id == 1 or .category_id == 2 ) ' instances_val2017.json | less -R

Однако возвращаются только элемент аннотаций из общего JSON, как показано ниже.

{
  "segmentation": [
    [
      162.72,
      ...
    ]
  ],
  "area": 426.9120499999995,
  "iscrowd": 0,
  "image_id": 45596,
  "bbox": [
    161.52,
    507.18,
    46.45,
    19.16
  ],
  "category_id": 2,
  "id": 124742
}
{
...
{

Я знаю, что можно вернуть эти элементы в виде массива, заключив выражение в [], но как я могу вернуть весь оригинал JSON после фильтрации идентификаторов указанных категорий?

1 Ответ

1 голос
/ 10 июля 2020

Хорошо, я потратил 3 часа, пытаясь решить эту проблему вчера, затем сегодня утром я опубликовал этот вопрос и впоследствии понял его!

Вот решение, которое использует оператор |=, который изменяет элемент на месте.

jq '.annotations |= map(select(.category_id | contains(1,2)))' instances_val2017.json

Согласно предложению @peak, вот команда с == вместо contains.

jq '.annotations |= map(select(.category_id == (1,2)))' instances_val2017.json
...