4 个版本
0.1.6 | 2019 年 5 月 18 日 |
---|---|
0.1.5 | 2019 年 5 月 11 日 |
0.1.4 | 2019 年 5 月 2 日 |
0.1.3 | 2019 年 5 月 2 日 |
#1096 在 文本处理
580KB
1.5K SLoC
Jeff Goldblum / jg 是一个命令行 JSON 处理器,它会在 JSON 输入中搜索结构化模式,并打印出与模式匹配的每个 JSON 对象。
有关 jg 创建背后的理由,请在此处查看:[链接](https://gidi.io/2019/03/01/structured-greping-of-structured-logging-using-grep-for-json.html)
概要
jg [−^cfimnqv] [−e pattern] [−f file] [−colour when] [pattern]
描述
jg 工具会搜索任何指定的输入文件,选择那些正确解析为有效 JSON 并匹配一个或多个 选择器模式 的行。
以下选项可用:
−c, −−count
只将选择的行数写入标准输出。
−−color=_when_, −−colour=_when_
使用转义序列包围匹配的 JSON 输入,以便在终端中以颜色显示。 when 可以是 never、always、always-cycle、auto 或 auto-cycle。 always 和 auto 选项使用单个默认颜色突出显示匹配项,不同之处在于 auto 只在输出到终端时突出显示内容。 always-cycle 和 auto-cycle 选项将循环通过颜色列表,每个匹配项使用不同的颜色。
−e pattern
指定在搜索 JSON 输入时使用的 选择器模式:如果输入行解析为有效 JSON 并匹配指定的任何 选择器模式,则选择该输入行。此选项在多个 −e 选项用于指定多个模式时最有用。
−−help
打印简短的帮助信息。
−i, −−ignore-case
执行不区分大小写的匹配。默认情况下,jg是区分大小写的。
−m num, −−max-count=_num_
在匹配到num次后停止读取文件。
−n, −−line-number
每行输出前都会显示其在文件中的相对行号,从1开始。
−q, −−quiet, −−silent
安静模式:抑制正常输出。 jg将只搜索文件,直到找到匹配项,这使得搜索可能更节省成本。如果你正在尝试确保文件中存在某个匹配项,并且可以依赖退出码来获取结果,这将很有用。参见 退出码 部分
−v, −−invert-match
选中的行是那些不匹配任何指定选择器模式的行。
−^, −−match-root
只有当选择器与JSON结构的根匹配时,才匹配对象。这意味着,例如,如果你的选择器是'.name',那么JSON结构必须在JSON对象本身上有一个name
属性,而不是内部对象。
选择器模式
选择器模式是一种描述JSON结构的方法,jg可以使用它来尝试匹配到从指定文件或管道输入中读取的JSON输入的结构。如果jg发现输入JSON包含由选择器模式指定的结构,则输入被认为是匹配的,并将打印出来。
例如,假设你消费了Nasa API,它返回一个描述现在有多少人在太空中的JSON数据集...
$ curl 'http://api.open-notify.org/astros.json'
...你可能会得到类似这样的响应
{
"people": [{
"name": "Oleg Kononenko",
"craft": "ISS"
}, {
"name": "David Saint-Jacques",
"craft": "ISS"
}, {
"name": "Anne McClain",
"craft": "ISS"
}],
"number": 3
}
如果你想使用cli来验证太空中有人,你可以使用jg来确保对象上有people属性。为此,我们可以使用属性匹配器,它匹配任何具有指定属性的JSON对象。
$ curl 'http://api.open-notify.org/astros.json' | jg '.people'
如果你这样做,你会看到cli打印出JSON对象,因为它是匹配的。
假设你了解到Nasa总是返回people属性,但它是空数组。幸运的是,模式可以链接起来,以描述提供输入中深层的复杂结构。我们将确保人员数组包含一个对象。
$ curl 'http://api.open-notify.org/astros.json' | jg '.people[.]'
JSON输出仍然在匹配,这很酷,但然后你意识到还有另一个问题,那就是身份匹配器,它匹配任何JSON值,也可以匹配Null。
为了避免将Null误认为是真正的宇航员,我们确保响应包含一个具有name的适当JSON对象
$ curl 'http://api.open-notify.org/astros.json' | jg '.people[.name]'
这样就可以了。
如果你使用curl请求API没有返回匹配,我们将知道太空中没有人。希望这种情况永远不会发生。
模式语法
身份: .
这是一个最直接的匹配器,因为它匹配任何和所有内容。这有助于打印出所有有效的JSON对象或匹配JSON数组中的非空序列,例如.people[.]
。
属性: .prop_name
此匹配器匹配任何具有指定属性名称的JSON对象。例如,在上面的模式中,任何具有"prop_name"名称的属性的对象都将被匹配。
属性 & 值: {"prop_name":"prop_value"}
此匹配器与 属性 模式相同,但还允许我们指定预期值。因此,例如,在上面的 模式 中,任何具有名称为 "prop_name" 且其值为字符串 prop_value 的属性的对象都将进行匹配。
属性的值可以是任何有效的 JSON 原始数据,这意味着它可以是 字符串、数字、布尔值 或 空值。
字符串值匹配器:
有几种方式可以用来匹配字符串的值,这些方式松散地基于 CSS 属性选择器 语法。
属性精确值: {"prop_name":"prop_value"}
匹配具有指定属性具有指定值的 JSON 对象。例如:{"prop_name":"prop_value"}
属性包含精确值: {"prop_name"~:"prop_value"}
匹配指定属性包含指定值作为 单词 的 JSON 对象。一个 单词 是由空格分隔的单词列表的单个部分。例如:{"prop_name":"This value will surely contain prop_value in it."}
属性前缀值: {"prop_name"^:"prop_value"}
匹配指定属性以指定值开头的 JSON 对象。例如:{"prop_name":"prop_value is what I'm all about."}
属性后缀值: {"prop_name"$:"prop_value"}
匹配具有指定属性以指定值结尾的JSON对象。例如:{"prop_name":"Know what I'm all about? It's prop_value"}
属性包含值:{"prop_name"*:"prop_value"}
匹配具有指定属性包含指定值的JSON对象。例如:{"prop_name":"Wildcard search for a the 'prop_value' is awesome"}
数组索引:[2]
此匹配器通过验证它是否包含指定索引处的值来与数组进行匹配。
例如:["some different value","member_value","some other value"]
数组 & 值:[="member_value"]
此匹配器通过验证它是否包含数组中的确切字符串 "member_value" 来与数组进行匹配。
与属性匹配器一样,数组成员的值可以是任何有效的JSON原语,这意味着它可以是 String、Number、Boolean 或 Null。
数组值匹配器:
有几种方法可以匹配数组中的值,这些方法类似于 属性 选择器的 字符串值匹配器,但略有不同,这是由于字符串和数组之间的差异。
数组精确值:[="member_value"]
匹配包含精确指定值的JSON数组,并且这是数组中的唯一单个值。这可以与所有 原语 一起使用。例如:["member_value"]
数组包含精确值:[~="member_value"]
匹配包含精确指定值的JSON数组。这可以与所有 原语 一起使用。例如:["some different value","member_value","some other value"]
数组前缀值: [^="member_value"]
匹配包含以指定值开头的值的JSON数组。这只能用于字符串。例如:["some different value","member_value is cool","some other value"]
数组后缀值: [$="member_value"]
匹配包含以指定值结尾的值的JSON数组。这只能用于字符串。例如:["some different value","Know what's cool? member_value","some other value"]
数组包含值: [*="_value"]
匹配包含数组中指定值的子字符串的JSON数组。例如:["Know what's cool? wildcard search of a member_value value","some other value"]
退出码
与grep一样,jg的退出码在文件中找到选择器匹配时返回退出状态0,如果没有匹配到选择器,则返回1。
安装
在解决所有问题之前,我们避免将jg发布到公共软件包管理器。话虽如此,在发布选项卡下,您可以找到OSX和Linux版本。
如果您在OSX上使用Homebrew,可以使用以下脚本来安装最新的OSX版本
brew install https://raw.githubusercontent.com/gmmorris/jg/master/packaging/homebrew.rb
如果您在linux上,我们已创建了多个二进制文件,包括针对受支持发行版的RPM,这些文件可在发布页面上找到。
如果您想使用RPM进行安装,可以使用以下命令:注意,下面的命令只是一个例子,您最好从发布页面获取最新的URL
yum install -y https://github.com/gmmorris/jg/releases/download/0.1.4/jg-0.1.4-x86_64-unknown-linux-gnu.rpm
示例
查找所有具有属性name
的对象的JSON输入
$ jg '.name' -f myfile
查找所有具有属性fellowship
的JSON输入,其值是一个数组,在该数组中有一个具有属性name
的JSON对象,其值为Aragorn
$ jg '.fellowship[{"name":"Aragorn"}]' -f myfile
查找所有根对象具有属性name
的JSON输入
$ jg -^ '.name' -f myfile
查找所有在其结构中任何地方都没有属性name
的JSON输入
$ grep -v '.name' -f myfile
依赖关系
~6–17MB
~218K SLoC