Передайте переменную массива в jq в bash - PullRequest
2 голосов
/ 15 октября 2019

Можно ли передать и использовать в jq переменную типа array?

jq --arg ips "${IPs[0]}" '.nodes.app.ip = $ips[0] | .nodes.data.ip = $ips[1]' nodes.json

1 Ответ

3 голосов
/ 15 октября 2019

Решение в общем случае состоит в том, чтобы передать этот массив в stdin с разделителями NUL:

IPs=( 1.2.3.4 5.6.7.8 )
original_doc='{"nodes": { "app": {}, "data": {} }}'

jq -Rn --argjson original_doc "$original_doc" '
  input | split("\u0000") as $ips
  | $original_doc
  | .nodes.app.ip = $ips[0]
  | .nodes.data.ip = $ips[1]
' < <(printf '%s\0' "${IPs[@]}")

... испускается как вывод:

{
  "nodes": {
    "app": {
      "ip": "1.2.3.4"
    },
    "data": {
      "ip": "5.6.7.8"
    }
  }
}

Это избыточно для массива IP-адресов, но работает в общем случае, даже для активно-враждебных массивов (с буквенными кавычками, буквальными символами новой строки и другими данными, которые намеренно трудно анализировать).


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

IPs=( 1.2.3.4 5.6.7.8 )
IPs_json=$(jq -Rns 'input | split("\u0000")' < <(printf '%s\0' "${IPs[@]}"))

jq --argjson ips "$IPs_json" '
    .nodes.app.ip = $ips[0]
  | .nodes.data.ip = $ips[1]
' <<<'{"nodes": { "app": {}, "data": {} }}'
...