jq 按日期过滤json

Jef*_*lin 7 json jq

我有一些看起来像这样的 json

 {
  "users":[ {  
     "id":8734,
     "last_login":"2016-10-04T06:59:40Z"
  },
  {  
    "id":9376,
    "last_login":"2016-05-04T20:37:32Z"
  },
  {  
    "id":9376,
    "last_login":null
  }
]}
Run Code Online (Sandbox Code Playgroud)

我想返回上次登录日期 > 90 天的 ID,因此在这种情况下它应该只返回 9376。我想我需要将 fromdateiso8601 与选择结合使用,但在正确使用语法时遇到了一些麻烦。

这似乎有效

.users[] | select ( .last_login | fromdateiso8601 > 1475625600) | .id 
Run Code Online (Sandbox Code Playgroud)

但我仍然得到

jq: error (at <stdin>:0): strptime/1 requires string inputs and arguments
Run Code Online (Sandbox Code Playgroud)

我如何处理空值,理想情况下这些将包含在结果中。

Jef*_*ado 7

只需添加适当的空检查。

.users[] | select (.last_login | . == null or fromdateiso8601 > 1475625600).id 
Run Code Online (Sandbox Code Playgroud)


pea*_*eak 6

防止 .last_login 为空值的一种方法如下:

.users[]
| select ( .last_login // empty | fromdateiso8601 > 1475625600)
| .id 
Run Code Online (Sandbox Code Playgroud)

不过,为了清楚起见,我添加了括号,例如:

.users[]
| select ( (.last_login // empty) | fromdateiso8601 > 1475625600)
| .id 
Run Code Online (Sandbox Code Playgroud)

或者更具防御性,使用?

.users[]
| select ( .last_login | fromdateiso8601? > 1475625600)
| .id 
Run Code Online (Sandbox Code Playgroud)

如果您想包含 .last_login 计算结果为 的项目null,那么您可以使用 Jeff 建议的过滤器,或者可能:

 (.last_login | fromdateiso8601? > 1475625600) // true
Run Code Online (Sandbox Code Playgroud)

PS 对于“现在之前的 90 天,以 Unix 纪元开始以来的秒数表示”,您可以使用:

def daysAgo(days):  (now | floor) - (days * 86400);
Run Code Online (Sandbox Code Playgroud)