[英]Looping over a list of keys to extract from a JSON file with jq
I'm trying to extract a series of properties (named in an input file) in jq and getting error when I feed those from bash via a loop: 我试图在jq中提取一系列属性(在输入文件中命名),并在通过循环从bash馈入这些属性时遇到错误:
while read line; do echo $line; cat big.json | jq ".$line"; sleep 1; done < big.properties.service
cfg.keyload.service.count
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
When i try to do it manually it works 当我尝试手动进行操作时
$ line=cfg.keyload.service.count
$ echo $line
cfg.keyload.service.count
$ cat big.json | jq ".$line"
1
Is there any way to get it work in loop? 有什么办法可以使其循环工作?
Here is example 这是例子
cat >big.json <<EOF
{
"cfg": {
"keyload": {
"backend": {
"app": {
"shutdown": {
"timeout": "5s"
},
"jmx": {
"enable": true
}
}
}
}
}
}
EOF
cat >big.properties.service <<EOF
cfg.keyload.backend.app.shutdown.timeout
cfg.keyload.backend.app.jmx.enable
cfg.keyload.backend.app.jmx.nonexistent
cfg.nonexistent
EOF
...output should be: ...输出应为:
cfg.keyload.backend.app.shutdown.timeout
"5s"
cfg.keyload.backend.app.jmx.enable
true
cfg.keyload.backend.app.jmx.nonexistent
null
cfg.nonexistent
null
The "invalid character" at hand here is almost certainly a carriage return. 这里的“无效字符”几乎可以肯定是回车。 Use
dos2unix
to convert your input file to a proper UNIX text file, and your original code will work (albeit very inefficiently, rereading your whole big.json
every time it wants to extract a single property). 使用
dos2unix
将您的输入文件转换为正确的UNIX文本文件,您的原始代码将起作用(尽管效率很低,每次要提取单个属性时都重新big.json
整个big.json
)。
Don't use a bash loop for this at all -- it's much more efficient to have jq
do the looping. 根本不要为此使用bash循环-让
jq
进行循环会更有效。
Note the sub("\\r$"; "")
used in this code to remove trailing carriage returns so it can accept input in DOS format. 请注意此代码中使用的
sub("\\r$"; "")
来删除尾随的回车符,以便它可以接受DOS格式的输入。
jq -rR --argfile infile big.json '
sub("\r$"; "") as $keyname
| ($keyname | split(".")) as $pieces
| (reduce $pieces[] as $piece ($infile; .[$piece]?)) as $value
| ($keyname, ($value | tojson))
' <big.properties.service
properly emits as output, when given the inputs in the question: 当给出问题的输入时,正确地发出作为输出:
cfg.keyload.backend.app.shutdown.timeout
"5s"
cfg.keyload.backend.app.jmx.enable
true
cfg.keyload.backend.app.jmx.nonexistent
null
cfg.nonexistent
null
Your properties file is effectively paths in the json that you want to retrieve values from. 您的属性文件实际上是您要从中检索值的json中的路径。 Convert them to paths that
jq
recognizes so you can get those values. 将它们转换为
jq
识别的路径,以便获得这些值。 Just make an array of keys that would need to be traversed. 只需排列一系列需要遍历的键即可。 Be sure to read your properties file as raw input (
-R
) since it's not json, and use raw output ( -r
) to be able to output the paths as you want. 由于它不是json,因此请确保将属性文件读取为原始输入(
-R
),并使用原始输出( -r
)来输出所需的路径。
$ jq --argfile big big.json '
., (split(".") as $p | $big | getpath($p) | tojson)
' -Rr big.properties.service
cfg.keyload.backend.app.shutdown.timeout
"5s"
cfg.keyload.backend.app.jmx.enable
true
cfg.keyload.backend.app.jmx.nonexistent
null
cfg.nonexistent
null
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.