[英]jq how to pass json keys from a shell variable
I have a json file I am parsing with jq
.我有一个 json 文件,我正在用jq
解析。 This is a sample of the file这是文件的示例
[{
"key1":{...},
"key2":{...}
}]
[{
"key1":{...},
"key2":{...}
}]
...
each line is a list containing a json (which I know is not technically a json
format but jq
still works on such a file)每行都是一个包含 json 的列表(我知道这在技术上不是json
格式,但jq
仍然适用于这样的文件)
The below jq
command works:下面的jq
命令有效:
cat file.json | jq -r '.[] | [.key1,.key2]'
The above correctly shows:以上正确显示:
[
<value_of_key1>,<value_of_key2>
]
[
<value_of_key1>,<value_of_key2>
]
However, I want .key1,.key2
to be dynamic since these keys can change.但是,我希望.key1,.key2
是动态的,因为这些键可以更改。 So I want to pass a variable to jq
.所以我想将一个变量传递给jq
。 Something like:就像是:
$KEYS=.key1,.key2
cat file.json | jq -r --arg var "$KEYS" '.[] | [$var]'
But the above is returning the keys themselves:但是上面是返回密钥本身:
[
".key1,.key2"
]
[
".key1,.key2"
]
why is this happening?为什么会这样? what is the correct command to make this happen?实现这一目标的正确命令是什么?
This answer does not help me. 这个答案对我没有帮助。 I am not getting any errors as the OP in that question.作为该问题的 OP,我没有收到任何错误。
Fetching the value of a jq variable doesn't cause it to be executed as jq code.获取 jq 变量的值不会导致它作为 jq 代码执行。
Furthermore, jq lacks the facility to take a string, compile it as jq code, and evaluate the result.此外,jq 缺乏获取字符串、将其编译为 jq 代码并评估结果的功能。 (This is commonly known as eval
.) (这通常称为eval
。)
So, short of a writing a jq parser and evaluator in jq, you will need to impose limits and/or accept a different format.因此,如果没有在 jq 中编写 jq 解析器和评估器,您将需要施加限制和/或接受不同的格式。
For example,例如,
keys='[ "key1", "key2" ]' # JSON
jq --argjson keys "$keys" '.[] | [ .[$keys[]] ]' file.json
or或者
keys='key1,key2' # Comma-separated (but not CSV)
jq --arg keys "$keys" '$keys / "," as $keys | .[] | [ .[$keys[]] ]' file.json
More complex paths could be supported rather simply (with the help of getpath
).可以相当简单地支持更复杂的路径(在getpath
的帮助下)。
Suppose you have:假设你有:
cat file
[{
"key1":1,
"key2":2
}]
[{
"key1":1,
"key2":2
}]
You can use a jq
command like so:您可以像这样使用jq
命令:
jq -r '.[] | [.key1,.key2]' file
[
1,
2
]
[
1,
2
]
Unfortunately, jq
does not have a type -e
to eval a string that Perl and Ruby have.不幸的是, jq
没有类型-e
来评估 Perl 和 Ruby 具有的字符串。 It DOES have an -f
to execute a filter from a file and nothing keeps you from creating the file separately from the shell variables.它确实有一个-f
可以从文件中执行过滤器,并且没有什么可以阻止您与 shell 变量分开创建文件。
Example:例子:
keys=".key1"
echo ".[] | [${keys}]" >jqf
jq -r -f jqf file
[
1
]
[
1
]
You can use --argjson
option and destructuring
.您可以使用--argjson
选项和destructuring
。
file.json文件.json
[{"key1":{"a":1},"key2":{"b":2}}]
[{"key1":{"c":1},"key2":{"d":2}}]
$ in='["key1","key2"]' jq -c --argjson keys "$in" '$keys as [$key1,$key2] | .[] | [.[$key1,$key2]]' file.json
output: output:
[{"a":1},{"b":2}]
[{"c":1},{"d":2}]
Elaborating on ikegami's answer.详细阐述池上的回答。
To start with here's my version of the answer:首先是我的答案版本:
$ in='key1.a,key2.b'; jq -c --arg keys "$in" '($keys/","|map(./".")) as $paths | .[] | [getpath($paths[])]' <<<$'[{"key1":{"a":1},"key2":{"b":2}}] [{"key1":{"a":3},"key2":{"b":4}}]'
This gives output这给出了 output
[1,2]
[3,4]
Let's try it.让我们试试吧。
We have input我们有输入
[{"key1":{"a":1},"key2":{"b":2}}]
[{"key1":{"a":3},"key2":{"b":4}}]
And we want to construct array我们要构造数组
[["key1","a"],["key2","b"]]
then use it on getpath(PATHS)
builtin to extract values out of our input.然后在内置的getpath(PATHS)
上使用它从我们的输入中提取值。
To start with we are given in
shell variable with string value key1.a,key2.b
.首先,我们in
shell 变量中给出了字符串值key1.a,key2.b
。 Let's call this $keys
.我们称之为$keys
。
Then $keys/","
gives然后$keys/","
给出
["key1.a","key2.b"]
["key1.a","key2.b"]
After that $keys/","|map(./".")
gives what we want.之后$keys/","|map(./".")
给出了我们想要的。
[["key1","a"],["key2","b"]]
[["key1","a"],["key2","b"]]
Let's call this $paths
.我们称之为$paths
。
Now if we do .[]|[getpath($paths[])]
we get the values from our input
equivalent to现在如果我们这样做.[]|[getpath($paths[])]
我们从我们的input
中得到值相当于
[.[] | .key1.a, .key2.b]
which is这是
[1,2]
[3,4]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.