【问题标题】:extract specific key value from json in bash if key matches如果键匹配,则从 bash 中的 json 中提取特定键值
【发布时间】:2019-06-12 18:21:24
【问题描述】:

我有一个 json 内容 (output.json)

{"project": {"id": "A", "content": [{"name": "XYZ", "location": "Berlin", "comments":""}, {"name": "ABC", "location": "NewYork", "comments": "Hwllo"}, {"name": "DEF", "location": "Paris", "comments": "Success"}]}}

name 匹配ABC 时,我想使用 bash 或 shell 命令从上述 json 中提取带有值的 location

我尝试了类似下面的方法,它在花括号内给出了内容。但不确定是否搜索特定键。

cat output.json | grep -o -e "{.*}"

输出预期: 如果name 匹配ABC,则输出为"location":"NewYork"

对进一步处理有什么建议吗?

【问题讨论】:

  • 如果可以的话,你应该使用 jq 从 json 中提取。根据作者的说法,“jq 就像 sed 用于 JSON 数据”。

标签: json regex linux bash shell


【解决方案1】:

如果可以的话,你应该使用 jq 从 json 中提取。根据作者的说法,“jq 就像 sed 用于 JSON 数据”(source)

在你的情况下应该是:

$ jq -r '.project' output.json | jq -r '.content' | jq '.[] | select(.name=="ABC")' | jq -r '.location'

输出将是:

NewYork

要获得您需要的输出:

"location":"NewYork"

你可以使用:

echo "\"location\":$(jq -r '.project' output.json | jq -r '.content' | jq '.[] | select(.name=="ABC")' | jq '.location')"

在你使用 jq 之前,你应该在 Debian 和 Ubuntu 上安装它:

$ sudo apt install jq

对于其他操作系统,您应该检查this site

【讨论】:

  • 谢谢。看起来很有趣,马上试试:)
【解决方案2】:

可能有更好的方法来做到这一点,这里是一种快速扭曲的方式。

cat output.json | sed 's/"name"/\n"name"/g' | grep '"name"' | awk -F',' '{print $2}'

如果需要根据名称进行过滤,也可以添加| grep <preferred name>

【讨论】:

  • 谢谢。这很好。但遗憾的是,关键位置并不总是排在第二位。 awk$2 就像硬编码一样。
  • ohh .. 好的,那么我们可以在此之前再添加一个 sed,例如 cat output.json | sed 's/"name"/\n"name"/g' | grep '"name"' | sed 's/"location"/\n"location"/g' | awk -F',' '{print $1}' ... ;)
  • 当我这样做时......我得到了名称和位置键值对。我仍然需要在最后使用tail -1,当订单不同时看起来不太好
  • 是的,它是真的...... ;)
【解决方案3】:

使用 Perl

$ perl -0777 -lne ' while(/"name":\s+"ABC",\s+"location":\s+(\S+)/msg) { print "$1\n" } ' output.json
"NewYork",
$ cat output.json
{"project": {"id": "A", "content": [{"name": "XYZ", "location": "Berlin", "comments":""}, {"name": "ABC", "location": "NewYork", "comments": "Hwllo"}, {"name": "DEF", "location": "Paris", "comments": "Success"}]}}
$

【讨论】:

  • 很高兴听到这个消息!.. 请考虑接受答案
【解决方案4】:

请使用 JSON 解析器来处理 JSON。
使用Xidel 很简单:

xidel -s output.json -e '($json//content)()[name="ABC"]/location'

或者:

xidel -s output.json -e '$json/(.//content)()[name="ABC"]/location'

or in full:

xidel -s output.json -e '$json/project/(content)()[name="ABC"]/location'

以上是 XPath 表示法 (example #11, Reading JSON)。点符号(如jq)也是可能的:

xidel -s output.json -e '($json).project.content()[name="ABC"].location'

[编辑]
上面的命令输出NewYork,我刚刚意识到您需要输出为"location":"NewYork"。 Xidel 也可以做到这一点:

xidel -s output.json -e '($json//content)()[name="ABC"]/concat("""location"":""",location,"""")'

[/edit]

【讨论】:

    猜你喜欢
    • 2020-06-05
    • 1970-01-01
    • 2020-10-30
    • 2019-12-27
    • 2021-02-08
    • 2021-05-26
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多