如何在没有`jq`的情况下获取JSON字段值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在没有`jq`的情况下获取JSON字段值?相关的知识,希望对你有一定的参考价值。
我正在有限的环境中尝试从JSON提取值,在该环境中我无法安装任何工具或从Internet下载任何内容。我在环境上可用的工具是busybox提供的基本工具,例如:awk
,grep
和sed
。没有像Perl和Python这样的编译器或解释器。
我尝试解析的JSON具有固定的方案,但是可以用任何有效的方式对其进行格式化,而我始终需要获取字段tag
的值。
可能的JSON示例:
{"version":1,"name":"2","tag":"3"}
{
"version": 1,
"tag": "3",
"name" :"2"
}
这可能对您有用(GNU sed):
sed -nE '$!{:a;N;$!ba;s/
//g;s/"tag":[^"]*"([^"]*)"/
1
TAG/g};/^[^
]*
TAG/P;D' file
这会将文件插入到内存中,删除所有换行符,将标签值反向并标记到单独的连续行上,并打印这两行的第一行。
可选,使用tr
,grep
和sed
:
tr -d '
' <file | grep -o '"tag":[^"]*"[^"]*"' | sed -E 's/".*".*"(.*)"/1/'
这将适用于您使用的数据格式(即不适用于可能的完整JSON语法),并且在每个UNIX框上的任何外壳中使用任何awk:
$ cat tst.awk
{ rec = rec $0 }
END {
gsub(/^[[:space:]]*{[[:space:]]*|[[:space:]]*}[[:space:]]*$/,"",rec)
while ( match(rec,/"[^"]+"[[:space:]]*:[[:space:]]*("[^"]*"|[^,]*)/) ) {
key = val = substr(rec,RSTART+1,RLENGTH-1)
sub(/".*/,"",key)
sub(/[^"]*"[[:space:]]*:[[:space:]]*/,"",val)
f[key] = val
rec = substr(rec,RSTART+RLENGTH)
}
print f[k]
}
$ echo '{"version":1,"name":"2","tag":"3"}' | awk -v k=tag -f tst.awk
"3"
$ cat file
{
"version": 1,
"tag": "3",
"name" :"2"
}
$ awk -v k=tag -f tst.awk file
"3"
您可以轻松输出所需的任何值:
$ awk -v k=name -f tst.awk file
"2"
$ awk -v k=version -f tst.awk file
1
并且修改以任意顺序输出多个值很简单,或者仅在一个键的值在一定范围内或基于其他键值之间的关系等时才输出一个键的值。例如:
$ cat tst.awk
{ rec = rec $0 }
END {
split(keys,ks,/,/)
gsub(/^[[:space:]]*{[[:space:]]*|[[:space:]]*}[[:space:]]*$/,"",rec)
while ( match(rec,/"[^"]+"[[:space:]]*:[[:space:]]*("[^"]*"|[^,]*)/) ) {
key = val = substr(rec,RSTART+1,RLENGTH-1)
sub(/".*/,"",key)
sub(/[^"]*"[[:space:]]*:[[:space:]]*/,"",val)
f[key] = val
rec = substr(rec,RSTART+RLENGTH)
}
if ( (f["version"] > 0) && (f["name"] != f["tag"]) ) {
for (i=1; i in ks; i++) {
k = ks[i]
print k, f[k]
}
}
}
$ awk -v keys=tag,version,name -f tst.awk file
tag "3"
version 1
name "2"
如果您不希望仅在gsub(/^"|"$/,"",val)
上方的循环中添加f[key] = val
,也可以从值周围去除引号。
如果您的awk不符合POSIX,则只需将每个[:space:]
更改为[ ]
。
以上是关于如何在没有`jq`的情况下获取JSON字段值?的主要内容,如果未能解决你的问题,请参考以下文章
我在jq中使用相同的语法来更改JSON值,但是有一个案例有效,而其他情况则转换为bash交互式,我该如何解决这个问题呢?
如何在没有 _id 参考的情况下获取 GraphqQL 列表中模型的填充值?