我有一个像这样的JSON字符串(MacOS):
[{
"id": 3624,
"created_at": "2016-10-21T20:51:16.000+08:00",
},
{
"id": 3625,
"created_at": "2016-10-22T08:09:16.000+08:00",
},
{
"id": 3626,
"created_at": "2016-10-23T09:19:55.000+08:00",
}]
我想从“2016-10-21”到“2016-10-22”选择“created_at”; 我想得到这样的结果:
[{
"id": 3624,
"created_at": "2016-10-21T20:51:16.000+08:00",
},
{
"id": 3625,
"created_at": "2016-10-22T08:09:16.000+08:00",
}]
有人能指出我正确的方向吗?
问题已解决。 现在,我使用此代码来选择日期,我希望它对其他人有用:
jq --arg s '2016-10-26T18:16' --arg e '2016-10-27T20:24' '[($s, $e) | strptime("%Y-%m-%dT%H:%M") | mktime] as $r
| map(select(
(.updated_at[:19] | strptime("%Y-%m-%dT%H:%M:%S") | mktime) as $d
| $d >= $r[0] and $d <= $r[1]))' <<< "$requestJson"
答案 0 :(得分:4)
对于更强大的解决方案,最好解析日期以获取其组件并比较这些组件。最接近的是使用strptime/1
来解析返回其组件数组的日期。然后比较组件以检查它是否在范围内。
strptime
返回的数组是组件:
year (%Y)
month (%m)
date (%d)
hours (%H)
minutes (%M)
seconds (%S)
day of week (%w)
day of year (%j)
由于您只是比较日期,因此比较应仅查看前3个组件。
$ jq --arg s '2016-10-21' --arg e '2016-10-22' '
[($s, $e) | strptime("%Y-%m-%d")[0:3]] as $r
| map(select(
(.created_at[:19] | strptime("%Y-%m-%dT%H:%M:%S")[0:3]) as $d
| $d >= $r[0] and $d <= $r[1]
))
' input.json
由于您在Mac上运行,我希望您的构建中可以使用这些方法。您可能必须调整日期格式以使其按预期工作。正如你在评论中看到的那样,我们不得不按摩它以使其有效。
答案 1 :(得分:1)
按要求使用命令行JSON解析器jq
:
注意:Jeff Mercado's helpful answer演示了许多优秀的高级jq
技术,但针对手头的具体问题,我相信基于 text 的方法答案要简单得多,同时还要足够灵活。
#!/usr/bin/env bash
# Create variable with sample input.
IFS= read -r -d '' json <<'EOF'
[
{
"id": 3624,
"created_at": "2016-10-21T20:51:16.000+08:00"
},
{
"id": 3625,
"created_at": "2016-10-22T08:09:16.000+08:00"
},
{
"id": 3626,
"created_at": "2016-10-23T09:19:55.000+08:00"
}
]
EOF
# Use `jq` to select the objects in the array whose .created_at
# property value falls between "2016-10-21:T20:51" and "2016-10-22T08:09"
# and return them as an array (effectively a sub-array of the input).
# (To solve the problem as originally stated, simply pass "2016-10-21"
# and "2016-10-22" instead.)
jq --arg s '2016-10-21T20:51' --arg e '2016-10-22T08:09' '
map(select(.created_at | . >= $s and . <= $e + "z"))
' <<<"$json"
参数--arg s '2016-10-21T20:51'
和--arg e '2016-10-22T08:09'
分别定义变量$s
(日期开始+时间范围)和$e
(日期结束+时间范围),在jq
脚本中使用。
函数map()
将包含的表达式应用于输入数组的所有元素,并将结果作为数组输出。
函数select()
接受一个过滤表达式:每个输入对象都是根据所包含的表达式计算的,只有当表达式求值为“truthy”值时才会传递输入对象。
表达式.created_at | . >= $s and . <= $e + "z"
访问每个输入对象的created_at
属性,并将其值发送到比较表达式,该表达式执行 lexical 比较,由于格式化日期+时间字符串 - 相当于按时间顺序比较。
请注意附加到范围端点的尾随"z"
,以确保它匹配前缀匹配端点的JSON字符串中的所有日期+时间字符串;例如,端点2016-10-22T08:09
应与2016-10-22T08:09:01
以及2016-10-22T08:59
匹配。
这种词汇方法允许您根据需要从头开始指定任意数量的组件,以缩小或扩大日期范围;例如--arg s '2016-10-01' --arg e '2016-10-31'
将匹配2016年10月整个月的所有条目。