在引号内匹配jq var

时间:2018-06-12 05:06:53

标签: templates variables jq

我正在尝试将“$ {FOO}”替换为“BAR”(请注意:“$ {FOO}”不是shell变量 - 这就是它在json中的显示方式,我无法控制JSON)

这有效:

echo '{ "name": "${FOO}" }' | \
    jq '.|(select (.name == "${FOO}") | .name) |= "BAR"'

{
  "name": "BAR"
}

但是,如果我想以编程方式分配匹配值(在这种情况下为MYVAR=FOO),我无法让它工作,例如。

echo '{ "name": "${FOO}" }' | \
    jq --arg MYVAR FOO '.|(select (.name == "${$MYVAR}") | .name) |= "BAR"'
{
  "name": "${FOO}"
}

我的直觉是匹配字符串周围的引号是问题,因为这也有效:

echo '{ "name": "FOO" }' | \
    jq --arg MYVAR FOO '.|(select (.name == $MYVAR) | .name) |= "BAR"'
{
    "name": "BAR"
}

1 个答案:

答案 0 :(得分:0)

首先,您永远不需要初始.|因为.这里只是“身份”过滤器。

其次,区分shell变量和jq $ -variables是很重要的。除非你明确地将两者结合在一起,否则它们将完全独立。如您所见,使用--arg MYVAR FOO将jq变量$MYVAR设置为JSON字符串"FOO";要引用此变量,只需在jq程序中编写$MYVAR即可。

使用:

初始化jq变量也没关系
--arg MYVAR "${MYVAR}"

这将jq变量设置为shell变量的(字符串)值。

第三,jq“$ -variables”的名称受到高度约束:排除最初的“$”,它们必须匹配正则表达式:[a-zA-Z _] [a-zA-Z_0-9] *

因此,如果您的真正目标是更改JSON字符串的出现次数 带有“BAR”的“$ {FOO}”,其中FOO将以编程方式指定, 你将不得不采取不同的策略。这个 会工作:

echo '{ "name": "${FOO}" }' |
  jq -c --arg MYVAR FOO --arg MYVALUE BAR '
    if .name == "${\($MYVAR)}" then .name = $MYVALUE else . end'

这会产生:{“name”:“BAR”}

另请参阅"Using jq as a template engine"中的jq Cookbook部分。