jq обновляет элементы списка на основе значений - PullRequest
0 голосов
/ 11 ноября 2018

Можно ли использовать jq, чтобы включить следующие данные JSON

[
    {
        "a": null,
        "b": [
            {
                "c": "cc",
                "d": "dd1"
            },
            {
                "c": "cc",
                "d": "dd1",
                "e": "ee",
                "f": "ff"
            }
        ]
    },
    {
        "b": [
            {
                "c": "cc",
                "d": "dd2",
                "e": "ee",
                "f": "ff"
            }
        ]
    }
]

в

[
    {
        "a": null,
        "b": [
            [
                "cc", "d1"
            ],
            [
                "cc", "d1", "ff"
            ]
        ]
    },
    {
        "b": [
            [
                "cc", "d2", "ff"
            ]
        ]
    }
]

Обратите внимание, что цель состоит в том, чтобы сократить список b с определенными элементами его элементов на основе условия. Условие присваивает строку d1, если значение d равно dd1, в противном случае d2 присваивается, если присутствует dd2.

Следующая неудачная попытка демонстрирует идею:

$ jq -r '.[].b[] = [.[].b[].c, ?, .[].b[].f?]'

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Без изменения значения клавиши d вы бы использовали этот фильтр jq:

jq '.[].b[]|=(to_entries|map(.value))' file

Обновляет массив b на все значения внутренних объектов.

Если вы хотите обновить d, вы можете использовать этот фильтр:

jq '.[].b[] |= (to_entries|
                  map(
                    if(.key=="d") then 
                       .value|=sub("d+";"d") 
                    else . 
                    end
                    |.value)
                )' file

, который добавляет проверку, является ли ключ d, соответствующее значение обновляется, чтобы удалить дублированный символ d из строки. Для этого требуется jq для поддержки регулярных выражений (чтобы можно было использовать функцию sub).

0 голосов
/ 11 ноября 2018

Это, вероятно, не лучший способ сделать то, что вы хотите, но он действительно получает желаемый результат и имеет условие, о котором вы спрашивали.

jq '.[].b |= map(
   [ .c,
     (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
     .f // empty
   ] )'
...