使用sed命令的正则表达式解析json文本


15

我有这个json文本:

{
    "buildStatus" : {
        "status" : "ERROR",
        "conditions" : [{
                "status" : "OK",
                "metricKey" : "bugs"
            }, {
                "status" : "ERROR",
                "metricKey" : "test_success_density"
            }, {
                "status" : "OK",
                "metricKey" : "vulnerabilities"
            }
        ],
        "periods" : []
    }
}

我想提取buildStatus的总体状态,即预期的输出为“ ERROR”

"buildStatus" : {
    "status" : "ERROR",
    ....
}

我在下面尝试了sed表达式,但是它不起作用,它返回OK

status= sed -E 's/.*\"buildStatus\":.*\"status\":\"([^\"]*)\",.*/\1/' jsonfile

我究竟做错了什么?

Answers:


16

不要使用正则表达式解析复杂的嵌套数据结构(如JSON或XML),而应使用适当的JSON解析器(如)jshon

首先,您需要安装它:

sudo apt-get install jshon

然后,您必须向其提供要通过标准输入进行解析的JSON数据,因此您可以使用管道(|)将另一个命令的输出重定向到那里,也可以将文件重定向到(< filename)。

提取所需数据所需的参数如下所示:

jshon -e "buildStatus" -e "status" -u
  • -e "buildStatus" 从顶级词典中选择带有“ buildStatus”索引的元素。
  • -e "status" 从上面选择的第二级字典中选择带有“状态”索引的元素。
  • -u 将所选数据从JSON转换为纯数据(即,此处删除字符串周围的引号)

因此,根据从何处获取数据,您运行的命令看起来像其中之一:

jshon -e "buildStatus" -e "status" -u < YOUR_INPUT_FILE
YOUR_JSON_PRODUCING_COMMAND | jshon -e "buildStatus" -e "status" -u

要了解更多信息jshon,您可以在此处在线阅读或通过键入内容来阅读其联机帮助页man jshon


6
还有jqjq -r .buildStatus.status
大师


@HTNW我从未喜欢过这个答案,因为“单个XML开放标记”(这是问的问题)一种常规语言(原则上您可以通过使用正则表达式来匹配标记,注释,cdata来构建完整的XML解析器。部分,并使用简单的堆栈来处理嵌套上下文)。但是,JSON中最“有趣”的常规语言是字符串文字。
Random832 '16

10

的工作jq

jq -r '.["buildStatus"]["status"]' file.json

可以缩短为:

jq -r '.buildStatus.status' file.json

-r--raw-output)输出不带json字符串格式(即不带引号)的字符串。

例:

% cat file.json                   
{
    "buildStatus" : {
        "status" : "ERROR",
        "conditions" : [{
                "status" : "OK",
                "metricKey" : "bugs"
            }, {
                "status" : "ERROR",
                "metricKey" : "test_success_density"
            }, {
                "status" : "OK",
                "metricKey" : "vulnerabilities"
            }
        ],
        "periods" : []
    }
}

% jq -r '.["buildStatus"]["status"]' file.json
ERROR

% jq -r '.buildStatus.status' file.json       
ERROR

如果尚未安装,请通过以下方式安装(在Universe库中可用):

sudo apt-get install jq 

8

如前所述,使用适当的API解析复杂的结构化数据更为可取。Python json为此提供了模块,我个人在脚本中使用了很多模块,因此很容易提取所需的字段:

$ python -c 'import sys,json;print json.load(sys.stdin)["buildStatus"]["status"]' <  input.txt
ERROR

这里发生的是,我们将输入文件重定向到python的stdin,并使用读取json.load()。它将成为一个具有“ buildStatus”键的python字典,并且包含另一个具有“ status”键的python字典。因此,我们只是在打印存储在另一个字典中的字典中键的值。很简单。

除了简单之外,另一个优点是python和该API都已预安装,并且默认情况下随Ubuntu一起提供。


6

您实际上可以在中执行此操作sed,但是我强烈建议您使用一种更为复杂的语言,该语言编写了用于处理JSON数据的工具。例如,您可以尝试perl或python。

现在,在您的简单示例中,您想要的只是的第一次出现"status",因此您可以执行以下操作:

$ sed -nE '/status/{s/.*:\s*"(.*)",/\1/p;q}' file.json 
ERROR

诀窍是-n避免打印,然后,如果该行与status/status/)相匹配,则将除所需部分外的所有内容删除s/.*:\s*"(.*)",/\1/p使该行和quit整齐。


我个人觉得这个等效的grep命令要简单得多:

$ grep -m1 -oP '"status"\s*:\s*"\K[^"]+' file.json 
ERROR

或者这个:

$ perl -ne 'if(s/.*"status"\s*:\s*"([^"]+).*/$1/){print;exit}' file.json 
ERROR

严重的是,如果您打算解析JSON文件,请不要尝试手动执行此操作。使用适当的JSON解析器。


或这个:grep -m 1 status file.json | tr -cd '[[:alnum:]]:' | cut -f2 -d':'
slowko 2016年

1
@ user1876040不客气。请记住接受其中一个答案(我建议使用ByteCommander,这是一个更好的解决方案),因此可以将问题标记为已回答)。
terdon

6

不是说您应该使用sed(我认为有人因为不写强制性警告而对我不满意),但是,如果您需要在下一行中搜索某些内容,buildStatus而您似乎想自己尝试的话,则需要告诉sed您阅读N命令的下一行

$ sed -rn '/buildStatus/N;s/.*buildStatus.*\n.*: "(.*)",/\1/p' file
ERROR

笔记:

  • -n 在我们要求之前不要打印任何东西
  • -r使用ERE(与相同-E
  • /buildStatus/N 找到此模式并阅读下一行
  • s/old/new/替换oldnew
  • .* 行上任意数量的任何字符
  • \n 新队
  • : "(.*)",保存在: "和之间出现的所有字符",
  • \1 向后引用已保存的模式
  • p 打印我们工作的零件

0

有一个典型的解释,说明为什么sed和类似的文本流处理工具不能很好地解析JSON和XML之类的结构化数据。我手头上没有,但是我想指出的是,在所有情况下(可能是最少情况下),所需的表达式很快变得非常复杂,而专门用于解析结构的替代工具则更多。在相同的解析下优雅,可读且高效。

就像穆鲁已经把一个评论jq应该是工作的工具。我个人也很高兴看到它被替换了好几次,因为我尝试解析相同的数据几乎没有成功,也没有成功。它甚至还具有格式化和控制输出的功能。我jsontool之所以喜欢它,是由于我目前忘记的一个或多个原因。

字节指挥官似乎建议jshon另一个答案。我没有使用过该工具,但它让我想起了xmlstarlet它的语法,还带有一些可自定义的输出显示。



3
考虑通过显示如何jsontool用于OP的特定案例的示例来改善您的答案
Sergiy Kolodyazhnyy 16/12/23

大声笑@muru,对,这是试图阻止使用Regex解析XML / JSON的帖子之一!我更建议jqmuru和heemayl描述已经有一些赞美诗,然后发布其背后的理由:askubuntu.com/a/863948/230721
Pysis

0

只是另一个名为json的Json工具(https://github.com/trentm/json

$ json buildStatus.status < file.json
ERROR

该案例研究具有误导性:看起来工具无法正常工作。您还可以json用于更改json文件:

$ json -e 'this.buildStatus.status="not error"' < file.json > new.json

甚至...

$ json -e 'this.buildStatus.status="no errors"' < file.json | json -e 'this.buildStatus.status
no errors

文档位于:http : //trentm.com/json/


如果未安装:

  • 安装节点
  • 和须藤 npm install -g json
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.