【发布时间】:2020-11-15 18:08:43
【问题描述】:
假设这是我的 json 文件内容:
[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]
我想知道 id "13" 是否在 json 文件中。
bash 有没有办法做到这一点?
我尝试使用 jq 和它的各种不同变体(例如包含和不包含)运行该命令,但没有任何东西可以为我回答这个查询。
【问题讨论】:
假设这是我的 json 文件内容:
[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]
我想知道 id "13" 是否在 json 文件中。
bash 有没有办法做到这一点?
我尝试使用 jq 和它的各种不同变体(例如包含和不包含)运行该命令,但没有任何东西可以为我回答这个查询。
【问题讨论】:
注意:当问题结束时,我在问题中添加了这个答案,以便重新打开问题:
(( $(jq < file.json '[.[].id | select(. == "13")] | length') > 0))
OP 说效率低下。我不知道为什么。它的作用如下:
它通过jq 程序传递 JSON,这是一个 JSON 解析器。 bash shell 对 JSON 没有原生理解,因此任何解决方案都将使用外部程序。其他程序会将 JSON 视为文本,并且可能在某些或大多数情况下有效,但最好使用像 jq 这样遵循正式 JSON 规范的程序来解析数据。
它创建一个数组来捕获...的输出
它遍历数组,挑选出所有id 字段
如果值为“13”,则输出id字段的值
计算数组的长度,即id值为“13”的字段个数
使用本机 bash,它将输出转换为数字,如果数字大于 0,则评估为 true,否则为 false。
我认为您不会发现正式遵循 JSON 规范的更高效的东西。
jq,这是 事实上的 标准 JSON 处理器。它不是 POSIX 标准(早于 JSON)的一部分,但它是最有可能安装在系统上的 JSON 处理器。bash 构造来解释输出和测试。jq 更高效的解决方案了,因为它运行零程序(bash 无法单独完成),也没有比jq 更好的程序了。jq 过滤器,因为它会处理整个输入(这就是它的工作原理),而select 过滤器会停止处理未通过测试的对象,这是全部或几乎全部。替代的“峰值”表示更紧凑、更优雅(好东西),但效率并没有显着提高(或降低)。它在帖子中看起来更好,因为很多东西都被遗漏了。完整的测试将是
[[ $(jq < file.json 'any(.[]; .id == "13")') == "true" ]]
实际上,.[]; 生成器是不必要的,所以更简洁的答案是
[[ $(jq < file.json 'any(.id == "13")') == "true" ]]
【讨论】:
这是一种可能性:
any(.[]; .id == "13")
【讨论】:
这是使用perl 确定给定“id”值是否存在的一种简单方法:
echo '[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]' | perl -00 -lne 'if (/"id":"13"/) {print "true"} else {print "false"}'
true
echo '[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]' | perl -00 -lne 'if (/"id":"33"/) {print "true"} else {print "false"}'
false
【讨论】:
[ { "id": "13" } ],并且仅包含{"key":{"id":"13"}} 2 个示例。尽管 JSON 不像 HTML 那样复杂,但许多反对使用正则表达式解析以this classic post 表示的 HTML 的论点仍然适用。