将参数传递给jq过滤器

lis*_*4ok 27 bash json parameter-passing jq

这是我的config.json:

{
    "env": "dev",
    "dev": {
        "projects" : {
            "prj1": {
                "dependencies": {},
                "description": ""
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的bash命令:

PRJNAME='prj1'

echo $PRJNAME

jq --arg v "$PRJNAME" '.dev.projects."$v"' config.json 
jq '.dev.projects.prj1' config.json 
Run Code Online (Sandbox Code Playgroud)

输出:

prj1
null
{
  "dependencies": {},
  "description": ""
}
Run Code Online (Sandbox Code Playgroud)

所以$ PRJNAME是prj1,但第一次调用只输出null.

有人能帮我吗?

小智 38

.dev.projects."$v"您的示例中的jq程序将逐字地尝试查找名为的键"$v".请尝试以下方法:

jq --arg v "$PRJNAME" '.dev.projects[$v]' config.json 
Run Code Online (Sandbox Code Playgroud)

  • 您可以多次使用`--arg`指令传递多个参数,如:`jq --arg foo 1 --arg bar 2 -n'[$ foo,$ bar]'` (7认同)
  • 从 [$v] 中删除 '' (2认同)

小智 9

正如上面评论中所问,有一种方法可以传递多个参数。也许有一种更优雅的方式,但它有效。

  • 如果您确定始终需要所有密钥,则可以使用以下命令:
jq --arg key1 $k1 --arg key2 $k2 --arg key3 $k3 --arg key4 $k4 '.[$key1] | .[$key2] | .[$key3] | .[$key4] '
Run Code Online (Sandbox Code Playgroud)
  • 如果不总是使用密钥,您可以这样做:
jq --arg key $k ' if key != "" then .[$key] else . end'
Run Code Online (Sandbox Code Playgroud)
  • 如果 key 有时指的是一个数组:
jq --arg key $k ' if type == "array" then .[$key |tonumber] else .[$key] end'
Run Code Online (Sandbox Code Playgroud)

当然你可以结合这些!


小智 7

--argjson当你制作你的json时你也可以使用它.

--arg a v   set variable $a to value <v>;
--argjson a v   set variable $a to JSON value <v>;
Run Code Online (Sandbox Code Playgroud)

  • 在传递不想用引号括起来的数字或布尔值时,您需要使用 `argjson`。 (9认同)

小智 5

你可以这样做:


    key="dev.projects.prj1"
    filter=".$key"
    cat config.json | jq $filter

Run Code Online (Sandbox Code Playgroud)