我需要从这一行获取“name”的值
"snapshots": [{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2",{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}
我希望输出是这样的
sLVZt
ubg9x
lo3Qp
答案1
假设您的 JSON 文档有效,例如
{"snapshots":[{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2"},{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}
或(因为非数据空白与格式无关),
{
"snapshots": [
{
"name": "sLVZt",
"user": "comment",
"current": "n",
"created": "2015-03-11 05:28:02"
},
{
"name": "ubg9x",
"user": "test2"
},
{
"name": "lo3Qp",
"user": "test3",
"current": "y",
"created": "2015-03-11 06:02:46"
}
]
}
jq
然后像这样使用:
$ jq -r '.snapshots[].name' file.json
sLVZt
ubg9x
lo3Qp
name
这会提取数组每个元素中键的值snapshots
。
您还可以通过多种方式根据其他键的值轻松过滤结果:
$ jq -r '.snapshots[] | select(.current == "y").name' file.json
lo3Qp
$ jq -r '.snapshots[] | select(.current != "n").name' file.json
ubg9x
lo3Qp
答案2
如果您使用的是 Linux 或以其他方式可以访问 GNU grep
,您可以执行以下操作:
$ grep -oP '"name":"\K[^"]+' file
sLVZt
ubg9x
lo3Qp
或者,在 Perl 中:
$ perl -lne 'print join "\n", /"name":"([^"]+)/g' file
sLVZt
ubg9x
lo3Qp
答案3
尝试这个,
sed 's/,/\n/g' file | awk -F '"' '$2~/name/ {print $(NF-1)}'
sLVZt
ubg9x
lo3Qp
答案4
纯粹awk
基于 - 的解决方案可能如下所示:
awk -F':' -v RS=',' '$1 ~ /"name"$/ {print $2}' file
这将获取输入并分割“记录”(通常意味着线) 处,
,然后将所有记录放入 处的字段中:
,每个记录留下两个字段。如果第一个字段结束在"name"
(这说明前导方括号/大括号)中,打印第二个字段,它是:
.
如果你想去掉支撑双引号,你可以使用
awk -F':' -v RS=',' '$1 ~ /"name"$/ {gsub("\"","",$2); print $2}' file
更新
由于修改后的示例输入包含前导"snapshots":
,其中还包含:
但以“不平衡”的方式,因此这将不再起作用。由于我的回答说“纯粹awk
基于”,唯一可能的适应将更加复杂,看起来像这样:
awk '{n=patsplit($0,field,"\"[^\"]*\":\"[^\"]*\""); for (i=1;i<=n;i++) {split(field[i],elem,":"); if (elem[1]=="\"name\"") print elem[2];};}' file
显然,这远不如grep
基于 - 的方法优雅,而且可移植性也较差(不适用于mawk
,eg)。