Удалить объект JSON, когда значение внутри объекта соответствует назначенному значению (jq)

avatar
hcdocs
1 июля 2021 в 18:00
243
1
0

Цель состоит в том, чтобы удалить весь объект в файле JSON, содержащий пару ключ/значение, указанную в сценарии JQ.

Например, все объекты с /unwanted-path/ в path будут удалены:

input.json:

[
    {
        "path": "/path-1/",
        "guide": "Guide 1"
    },
    {
        "path": "/path-2/",
        "guide": "Guide 2"
    },
    {
        "path": "/unwanted-path/",
        "guide": "Guide 3"
    }
]

output.json:

[
    {
        "path": "/path-1/",
        "guide": "Guide 1"
    },
    {
        "path": "/path-2/",
        "guide": "Guide 2"
    }
]

Этот сценарий JQ наиболее близок к потенциально успешному подходу, к которому я пришел, но, конечно, его намерения отличаются и не достигают цели.

jq '.[] | walk(if type == "object" then del(.path) else . end)' original.json > modified.json

Есть ли способ добавить туда логику, определяющую ключ для path?

Ключ всегда будет path, но есть несколько значений path, по которым я буду фильтровать. Если есть способ фильтрации по более чем одному path значению времени, это идеально, но не критично.

Источник
Inian
1 июля 2021 в 18:46
0

Ожидается ли, что вы также будете иметь path во вложенной области? или только внутри массива верхнего уровня?

hcdocs
1 июля 2021 в 23:45
0

@Inian, твой вопрос для меня сложный, но, если я правильно понимаю, он не будет вложенным.

Ответы (1)

avatar
jpseng
1 июля 2021 в 20:32
2

В следующем коде показано, как решить вашу задачу на четырех примерах

#!/bin/bash

FILE='
[
    {
        "path": "/path-1/",
        "guide": "Guide 1"
    },
    {
        "path": "/unwanted-path-2/",
        "guide": "Guide 2"
    },
    {
        "path": "/path-3/",
        "guide": "Guide 3",
        "sub": [
            {
                "path": "/unwanted-path-4/",
                "guide": "Guide 4"
            },
            {
                "path": "/path-5/",
                "guide": "Guide 5"
            },
            [
                {
                    "path": "/path-6/",
                    "guide": "Guide 6"
                },
                {
                    "path": "/unwanted-path-7/",
                    "guide": "Guide 7"
                }
            ]
        ]
    }
]
'

UNWANTED='/unwanted-path-2/'
echo "example 1: keep only objects in array that does not have the unwanted path '$UNWANTED' (narrow search)"
jq --arg unwantedPath "$UNWANTED" \
   'map(select(.path != $unwantedPath))' <<< "$FILE"

UNWANTED='/unwanted-path-7/'
echo -e "\nexample 2: delete objects that have the unwanted path '$UNWANTED' exactly (deep search)"
jq --arg unwantedPath "$UNWANTED" \
   'del(..| objects | select(.path == $unwantedPath)) ' <<< "$FILE"

UNWANTED='unwanted'
echo -e "\nexample 3: delete objects that have the unwanted path '$UNWANTED' partially (deep search)"
jq --arg unwantedPath "$UNWANTED" \
   'del(..| objects | select(.path | index($unwantedPath) != null)) ' <<< "$FILE"

UNWANTED='["/unwanted-path-4/", "/unwanted-path-7/"]'
echo -e "\nexample 4: delete objects that have one of unwanted paths '$UNWANTED' (deep search)"
jq --argjson unwantedPath "$UNWANTED" \
   'del(..| objects | select(.path | IN($unwantedPath[]))) ' <<< "$FILE"

пример вывода 1: оставить в массиве только объекты, которые не имеют нежелательного пути '/unwanted-path-2/' (узкий поиск)

[
  {
    "path": "/path-1/",
    "guide": "Guide 1"
  },
  {
    "path": "/path-3/",
    "guide": "Guide 3",
    "sub": [
      {
        "path": "/unwanted-path-4/",
        "guide": "Guide 4"
      },
      {
        "path": "/path-5/",
        "guide": "Guide 5"
      },
      [
        {
          "path": "/path-6/",
          "guide": "Guide 6"
        },
        {
          "path": "/unwanted-path-7/",
          "guide": "Guide 7"
        }
      ]
    ]
  }
]

пример вывода 2: удалить объекты, которые имеют нежелательный путь '/unwanted-path-7/' точно (глубокий поиск)

[
  {
    "path": "/path-1/",
    "guide": "Guide 1"
  },
  {
    "path": "/unwanted-path-2/",
    "guide": "Guide 2"
  },
  {
    "path": "/path-3/",
    "guide": "Guide 3",
    "sub": [
      {
        "path": "/unwanted-path-4/",
        "guide": "Guide 4"
      },
      {
        "path": "/path-5/",
        "guide": "Guide 5"
      },
      [
        {
          "path": "/path-6/",
          "guide": "Guide 6"
        }
      ]
    ]
  }
]

пример вывода 3: частичное удаление объектов с нежелательным путем (глубокий поиск)

[
  {
    "path": "/path-1/",
    "guide": "Guide 1"
  },
  {
    "path": "/path-3/",
    "guide": "Guide 3",
    "sub": [
      {
        "path": "/path-5/",
        "guide": "Guide 5"
      },
      [
        {
          "path": "/path-6/",
          "guide": "Guide 6"
        }
      ]
    ]
  }
]

пример вывода 4: удаление объектов с одним из нежелательных путей '["/unwanted-path-4/", "/unwanted-path-7/"]' (глубокий поиск)

[
  {
    "path": "/path-1/",
    "guide": "Guide 1"
  },
  {
    "path": "/unwanted-path-2/",
    "guide": "Guide 2"
  },
  {
    "path": "/path-3/",
    "guide": "Guide 3",
    "sub": [
      {
        "path": "/path-5/",
        "guide": "Guide 5"
      },
      [
        {
          "path": "/path-6/",
          "guide": "Guide 6"
        }
      ]
    ]
  }
]