jq создать объект с именем свойства из переменной

Вопрос или проблема

$ n="foo"; echo "{}" | jq --arg n "$n" '. += { "$n": $n }'
{
  "$n": "foo"
}

Моё понимание https://jqlang.github.io/jq/manual/#types-and-values предполагает, что это должно работать, но явно это не так. В чём дело?

Вы можете добиться этого, обернув $n в скобки, чтобы сказать jq оценить выражение:

n="foo"; echo "{}" | jq --arg n "$n" '. += { ($n): $n }'

Или, вероятно, более подходящим для этой задачи будет jo(1):

$ jo "$n"="$n"
{"foo":"foo"}

Я не уверен, ошибаются ли в документации или моё понимание недостаточно высоким, но, похоже, там говорится, что ваш пример должен работать:

Выражения ключей отличные от постоянных литералов, идентификаторов или ссылок на переменные должны быть в скобках, например, {(“a”+”b”):59}.

И кто-то мог бы предположить, что это относится к родной переменной jq, а не к одной, инъектированной оболочкой, поскольку они немного различаются, но, увы, обе должны быть обернуты в скобки:

$ echo '{}' | jq 'def myvar: "foo"; {myvar: myvar}'
{
  "myvar": "foo"
}
$ echo '{}' | jq 'def myvar: "foo"; {(myvar): myvar}'
{
  "foo": "foo"
}

Вы можете использовать:

$ n=foo
$ jq -cn --arg n "$n" '{$n:$n}'
{"foo":"foo"}

То есть использовать переменную $n в качестве ключа, а не строку "$n". jq -n аналогично echo null | jq.

$ jq -cn --arg n "$n" '.[$n]=$n'
{"foo":"foo"}

При этом не используется конструктор объекта {...}, а просто присваивается значение для данного ключа.

$ jq -cn --arg n "$n" '{"key\($n)":$n}'
{"keyfoo":"foo"}

Показывая, как разыменовать переменную jq внутри строкового литерала (в \(expr) expr может быть любым выражением jq, не только переменной).

$ jq -cn --arg n "$n" '{("key"+$n):$n}'
{"keyfoo":"foo"}

В конструкторе объекта, когда ключи должны быть результатом выражения jq, они должны находиться внутри (...).

Ответ или решение

Для создания объекта с использованием переменной в качестве имени свойства в jq, необходимо правильно использовать синтаксис, позволяющий указать ключи объектов с переменными. Ваш первоначальный пример не сработал, потому что вы использовали строку "$n" вместо самой переменной n. Для того чтобы правильно указать переменную в качестве ключа объекта, нужно обернуть её в круглые скобки.

Вот несколько способов сделать это:

  1. Использование скобок для переменной:

    Используйте следующий код, чтобы добавить переменную в качестве ключа:

    n="foo"
    echo "{}" | jq --arg n "$n" '. += { ($n): $n }'

    Выходом будет:

    {
     "foo": "foo"
    }

    Заметьте, что вы используете ($n) внутри фигурных скобок, что позволяет jq понять, что это переменная.

  2. Использование jq -n:

    Для создания объекта с нуля, можно использовать ключ -n, который позволяет избежать необходимости начинать с пустого JSON:

    n="foo"
    jq -cn --arg n "$n" '{$n: $n}'

    Это также даст вам:

    {
     "foo": "foo"
    }
  3. Использование динамических ключей:

    Вы можете использовать динамичные выражения для построения ключей. Например, если хотите создать ключ с префиксом, сделайте так:

    jq -cn --arg n "$n" '{("key" + $n): $n}'

    Результат будет:

    {
     "keyfoo": "foo"
    }
  4. Доступ к значению по ключу:

    Если необходимо создать или модифицировать объект, используя переменную в качестве ключа, используйте:

    jq -cn --arg n "$n" '.[$n] = $n'

    Это также создаст объект с результатом:

    {
     "foo": "foo"
    }

Все эти методы демонстрируют, как правильно работать с переменными в jq для создания объектов с динамическими названиями свойств. Настоятельно рекомендуется всегда использовать круглые скобки при работе с изменяемыми ключами в объектах jq, чтобы избежать неожиданного поведения.

Оцените материал
Добавить комментарий

Капча загружается...