我试图在 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:
当我尝试手动执行时,它会起作用
$ line=cfg.keyload.service.count
$ echo $line
cfg.keyload.service.count
$ cat big.json | jq ".$line"
1
有没有办法让它循环工作?
这里是例子
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
...输出应该是:
cfg.keyload.backend.app.shutdown.timeout
"5s"
cfg.keyload.backend.app.jmx.enable
true
cfg.keyload.backend.app.jmx.nonexistent
null
cfg.nonexistent
null
最佳答案
即时问题 - 无效输入
这里的“无效字符”几乎可以肯定是回车。使用 dos2unix
将您的输入文件转换为适当的 UNIX 文本文件,您的原始代码将工作(尽管效率很低,每次需要重新读取整个 big.json
提取单个属性)。
高性能实现 - 在 JQ 中循环,而不是 Bash
根本不要为此使用 bash 循环——让 jq
执行循环会更有效率。
请注意此代码中使用的 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
当给定问题中的输入时,正确地作为输出发出:
cfg.keyload.backend.app.shutdown.timeout
"5s"
cfg.keyload.backend.app.jmx.enable
true
cfg.keyload.backend.app.jmx.nonexistent
null
cfg.nonexistent
null
关于json - 遍历键列表以使用 jq 从 JSON 文件中提取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49920852/