首页 > 解决方案 > 当日期与查询匹配时,我需要选择一个 ID

问题描述

我的 json.file

[  
  {
    "id": 0000001,
    "created_at": "2021-01-28T17:29:35.888Z"
  },
  {
    "id": 0000002,
    "created_at": "2020-12-11T17:29:38.655Z"
  },
  {
    "id": 0000003,
    "created_at": "2020-12-11T17:29:37.233Z"
  },
  {
    "id": 0000004,
    "created_at": "2020-03-30T16:23:59.682Z"
  }
]  

我的查询

第一:我得到当天的日期

( now | gmtime | strftime("%Y-%m-%dT%H:%M:%S.%Z") 

然后:我将它转换为一个数组

| strptime("%FT%T.%Z") [0:6] ) as $f 

然后:我希望它只显示符合我条件的 id

| map(select(
    .id | $f[0] == (.[].created_at | strptime("%FT%T.%Z")[0]) and
          $f[1] == (.[].created_at | strptime("%FT%T.%Z")[1])
))

如果发现条件正确,它会向我显示所有记录。但我只需要匹配的 id。我的错误是什么?

我得到的结果:

[
  {
    "id": 1,
    "created_at": "2021-01-28T17:29:35.888Z"
  },
  {
    "id": 2,
    "created_at": "2020-12-11T17:29:38.655Z"
  },
  {
    "id": 3,
    "created_at": "2020-12-11T17:29:37.233Z"
  },
  {
    "id": 4,
    "created_at": "2020-03-30T16:23:59.682Z"
  }
]

我期望的结果:

{
    "id": 1,
    "created_at": "2021-01-28T17:29:35.888Z"
  },

标签: jsondatefilterjq

解决方案


你只需要这样:

( now | gmtime | strftime("%Y-%m") ) as $this_month
| .[]
| select( .created_at | startswith($this_month) )

jq 玩

这个答案的其余部分解决了 OP 的代码。


问题 #0

这不是一个真正的问题,但正在做很多必要的工作。gmtime已经返回日期时间组件的数组,所以

now | gmtime | strftime("%Y-%m-%dT%H:%M:%S.%Z") | strptime("%FT%T.%Z")[0:6]

又名

now | gmtime | strftime("%FT%T.%Z") | strptime("%FT%T.%Z")[0:6]

简化为

now | gmtime[0:6]

此外,切片是不需要的。

now | gmtime

警告:在这个新版本中,秒部分是小数(例如 23.489198923110962)而不是整数(例如 23),但这对我们来说不是问题。


问题 #1

.id.[].created_at没有意义。

.id | $f[0] == ( .[].created_at | strptime("%FT%T.%Z")[0] ) and
      $f[1] == ( .[].created_at | strptime("%FT%T.%Z")[1] )

应该

$f[0] == ( .created_at | strptime("%FT%T.%Z")[0] ) and
$f[1] == ( .created_at | strptime("%FT%T.%Z")[1] )

这与以下相同:(只是我的偏好)

( .created_at | strptime("%FT%T.%Z")[0] ) == $f[0] and
( .created_at | strptime("%FT%T.%Z")[1] ) == $f[1]

我们可以排除.created_at

.created_at | strptime("%FT%T.%Z")[0] == $f[0] and
              strptime("%FT%T.%Z")[1] == $f[1]

我们也可以排除调用strptime

.created_at | strptime("%FT%T.%Z") | .[0] == $f[0] and .[1] == $f[1]

这让我们明白了这一点:

( now | gmtime ) as $f 
| map(select( .created_at | strptime("%FT%T.%Z") | .[0] == $f[0] and .[1] == $f[1] ))

jq 玩


问题 #2

我们需要展平阵列。

... | map(select(...))

应该

... | map(select(...)) | .[]

当然,我们可以先展平,让我们消除使用map.

... | .[] | select(...)

这让我们明白了这一点:

( now | gmtime ) as $f 
| .[]
| select(
   .created_at
   | strptime("%FT%T.%Z")
   | .[0] == $f[0] and .[1] == $f[1]
)

jq 玩


推荐阅读