Gru*_*lon 4 macos shell json jq
我有一个像这样的 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",
}]
Run Code Online (Sandbox Code Playgroud)
我想从“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",
}]
Run Code Online (Sandbox Code Playgroud)
有人可以指出我正确的方向吗?
问题已经解决了。 现在,我使用此代码选择精确到分钟的日期,希望对其他人有用:
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"
Run Code Online (Sandbox Code Playgroud)
mkl*_*nt0 10
jq根据要求使用命令行 JSON 解析器:
注意: Jeff Mercado 的有用答案展示了许多出色的先进jq技术,但对于当前的具体问题,我相信此答案中基于文本的方法要简单得多,同时仍然足够灵活。
#!/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"
Run Code Online (Sandbox Code Playgroud)
参数--arg s '2016-10-21T20:51'和--arg e '2016-10-22T08:09'分别定义变量$s(日期+时间范围的开始)和$e(日期+时间范围的结束),以在jq脚本内使用。
函数map()将包含的表达式应用于输入数组的所有元素,并将结果也作为数组输出。
函数select()接受过滤表达式:每个输入对象都会根据所包含的表达式进行计算,并且仅当表达式计算结果为“真实”值时才会传递输入对象。
表达式.created_at | . >= $s and . <= $e + "z"访问每个输入对象的created_at属性并将其值发送到比较表达式,该比较表达式执行词法比较,由于日期+时间字符串的格式,这相当于按时间顺序比较。
"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 月整个月份的所有条目。
对于更强大的解决方案,最好解析日期以获取其组件并比较这些组件。您可以获得的最接近的是用于strptime/1解析返回其组件数组的日期。然后比较组件以检查它是否在范围内。
strptime返回的数组是组件:
year (%Y)
month (%m)
date (%d)
hours (%H)
minutes (%M)
seconds (%S)
day of week (%w)
day of year (%j)
Run Code Online (Sandbox Code Playgroud)
由于您只比较日期,因此比较应该只查看前 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
Run Code Online (Sandbox Code Playgroud)
由于您在 Mac 上运行,我希望您可以在构建中使用这些方法。您可能需要对日期格式进行调整才能使其按预期工作。正如您在评论中看到的那样,我们必须对其进行一些按摩才能使其发挥作用。
| 归档时间: |
|
| 查看次数: |
6339 次 |
| 最近记录: |