我知道这里已经被问过1000次了,但是我读了很多类似的问题,但仍然没有找到正确的方法。我需要从看起来像这样的一行中提取一个数字:
{"version":"4.9.123M","info":{"version":[2034.2],"description":""},"status":"OK"}
预期产量:
2034.2
该版本号并不总是相同的,但该行的其余部分应该相同。
我曾尝试使用sed,但我对此并不陌生,但失败了:
sed -e 's/version":[\(.*\),"description/\1/'
输出:
sed: -e expression #1, char 35: unterminated `s' command
我认为问题在于该行中包含太多特殊字符,并且我编写的命令不是很好。
由于它是JSON,因此应使用JSON感知工具进行处理。例如,如果您喜欢awk,则方法是使用GNU awk的JSON扩展。这是一个小方法。
首先下载并编译GNU awk,Gawkextlib和gawk-json的适当版本。这是非常简单的,实际上,只是./configure
和make
。然后,编写一些代码:
awk ' @load "json" # enable json extension { lines=lines $0 # read json file records and buffer to var lines if(json_fromJSON(lines,data)==1) { # once the json is complete for(i in data["info"]["version"]) # that seems to be an array so all elements print data["info"]["version"][i] # are outputed lines="" # once done with the first json object } # reset the var for more lines }' file
这次输出:
2034.2
解释更多:
JSON文件结构可以从一行到多行变化,例如:
{"version":"4.9.123M","info":{"version":[2034.2],"description":""},"status":"OK"}
要么:
{ "version": "4.9.123M", "info": { "version": [ 2034.2 ], "description": "" }, "status": "OK" }
因此我们需要使用缓冲JSON行,lines=lines $0
直到variable中有一个完整的有效对象为止lines
。我们使用扩展函数json_fromJSON()
来确定的有效性if(json_fromJSON(lines,data)==1)
。验证后,对象将解开并存储到array中data
。对于此特定对象,数组的结构为:
data["version"]="4.9.123M" data["info"]["version"][1]="2034.2" data["info"]["description"]="" data["status"]="OK"
我们可以使用此递归数组扫描功能检查对象并产生一些输出:
awk ' @load "json" function scan(a,p, q) { # a is array, p path to it, q is qnd * if(isarray(a)) for(i in a) { q=p (p==""?"":"->") i scan(a[i],q) } else print p ":" a } { lines=lines $0 if(json_fromJSON(lines,data)==1) scan(data) # }' file.json
输出:
status:OK version:4.9.123M info->version->1:2034.2 info->description:
*)快脏了
这是有关如何从数组输出JSON的简短示例:https : //stackoverflow.com/a/58109715/4162356