我正在解析一个API,它向我发送一个JSON响应,如下所示:
{
"newList": {
"243": {
"id": "243",
"name": "test",
"create": {
"date": "2017-08-31 13:57:29"
}
},
"244": {
"id": "244",
"name": "test",
"create": {
"date": "2017-08-31 13:57:29"
}
}
}
}
字符串
我试图得到名称和创建日期,使用bash与jq,所以几乎没有成功。
jq '.newList'确实可以工作,并将我降低了一个级别,但这还不够。
jq '.newList .243'给了我一个编译错误。此外,243是动态的,可以随时改变。我做错什么了?
2条答案
按热度按时间slwdgvem1#
假设根节点名称为
newList
,如您在给出的问题中所示,要获得id
和创建日期,您可以使用jq
执行字符串插值字符串
这样,过滤器就独立于节点中的动态数字(
243
,244
)。如果需要带引号的输出,请删除--raw-output
标志。要在循环中进一步处理,可以在bash循环上迭代,
型
如果您担心任何字段中的空格,则更仔细地分隔单词,在过滤器中使用
|
作为"\(.id)|\(.name)|\(.create.date)"
的分隔符,并在while循环中使用read
命令,通过设置IFS=|
,以便适当地存储变量。始终使用官方jq - documentation寻求帮助,并使用这个不错的Playground来测试过滤器,jq - online
nzkunb0c2#
第一,容易的部分:您需要
.newList."243"
(带双引号)才能访问"243"
详细信息。jq将.243
解释为数字而不是字符串,并且对象键都是字符串。但正如你所说,你事先不知道密钥,所以我们不能使用特定的密钥。没关系,如果我们需要的话,有办法得到它们。在任何情况下,您的原始问题都只要求输入name和create_date,因此我们可以忽略数字键
简单版本
要丢弃键,我们可以使用
values
过滤器,然后使用map
对值应用其他过滤器。所以我们的解决方案看起来就像cat input.json | jq ' .newList | values | map(some_filter) '
。some_filter
是什么?它是我们想要的任何东西,只要它能接收正确的对象,并输出我们想要的输出.我过去常常尝试用一行程序来编写这些东西,但我发现如果使用def关键字来定义自己的过滤器(就像在其他语言中定义helper-functions一样),那么考虑jq要容易得多我建议的解决方案:
字符串
这是如何工作的?
.newList
过滤器,结果是newList对象({ "243": X, "244": Y }
,其中X
和Y
是较小的JSON对象values
过滤器,结果是一个值数组([ X, Y]
,其中X
和Y
是与上述相同的较小JSON对象)map(details_to_string)
。Map接受一个数组,并通过details_to_string
过滤器来更改数组中的每一项。因此,它接收像[X_details_object, Y_details_object]
这样的数组,并输出像[X_string, Y_string]
这样的数组产量是多少?
型
如果你只需要单个的字符串(没有方括号,没有逗号),那么你可以把数组的末尾分开。(
.newList | values | map(details_to_string) | .[]
)的最大值。如果您还将“jq”更改为“jq-r”,则也将去掉引号如果只需要列表中的第一个项目,则可以使用
.[0]
提取该项目:.newList | values | .[0] | details_to_string
(请注意,我们现在已经取消了数组,因此不再需要map
)。更有趣的版本
在上面的评论中,您询问了如何捕获和包含键“243”和“244”,并且您提到这些字符串在名为“id”的字段中不可用,就像在原始示例中一样。为此,我认为最好使用一个名为
to_entries
的过滤器to_entries
通过将对象的键和值都转换为值来使它们可用。对象中的每一个键值对都变成了一个“入口”对象,看起来像{ "key": some_key, "value": some_value}
。注意,“key”和“value”实际上是字符串“key”和“value,”所以像{ "243": "alpha", "244": "Beta"}
这样的对象变成了像[ {"key": "243", "value": "alpha"}, {"key": "244", "value": "beta"} ]
这样的数组。这使得密钥可用,但也很难跟踪数据在系统中移动时的结构。这就是我发现将东西拉出到函数中确实有帮助的地方
型
产出:
型
在此版本中,您将获得一个中间步骤,其中包含类似'[“244”,“test”,“2017-08-31 13:57:29”]的值,这将为结果排序提供一些选项。(数组首先按第一个字段排序,然后按第二个字段排序,依此类推)
newList | to_entries | map(entry_to_list) | sort | map(list_to_string)
(在转换为字符串之前对条目进行排序)newList | to_entries | map(entry_to_list) | min | list_to_string
(在转换为字符串之前选择最低的条目)