Y.Y Y.Y - 1 month ago 9
JSON Question

How to select a date range from a JSON string by using jq?

I have a JSON string like this (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",
},]


I wanna select "created_at" from "2016-10-21" to "2016-10-22";
I wanna get result like this:

[{
"id": 3624,
"created_at": "2016-10-21T20:51:16.000+08:00",
},
{
"id": 3625,
"created_at": "2016-10-22T08:09:16.000+08:00",
}]


Can someone point me in the right direction?

Answer

Using command-line JSON parser jq, as requested:

#!/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 starts with either "2016-10-21" or "2016-10-22"
# and return them as an array (effectively a sub-array of the input).
jq 'map(select(.created_at | test("^2016-10-2[12]")))' <<<"$json"
  • Function map() applies the enclosed expression to all the elements of the input array and outputs the results as an array, too.

  • Function select() accepts a filtering expression: every input object is evaluated against the enclosed expression, and the input object is only passed out if the expression evaluates to a "truthy" value.

  • Expression .created_at | test("^2016-10-2[12]") accesses each input object's created_at property and sends its value to the test() function, which matches the input against a PCRE (Perl-compatible regular expression) and returns true for a match, false otherwise.

Comments