简体   繁体   中英

Get dates from json log file using JQ

I have a huge file in this format:

{
  "Name": "Alex",
  "Id": 1,
  "time": "2022-01-01T04:29:18.9099882Z"
}
{
  "Name": "Homer",
  "Id": 2,
  "time": "2022-01-02T04:29:18.9099882Z"
}
{
  "Name": "Bart",
  "Id": 3,
  "time": "2022-01-03T04:29:18.9099882Z"
}

How can I filter this file by date range and specific period of time? I was trying to solve this using jq, but was not able to do so. If there another way how to filter it without jq, please let me know.

Doesn't a simple select do what you want? For example using plain string comparison makes easy date ranges inclusive on the left and exclusive on the right:

jq 'select(.time > "2022-01-01" and .time < "2022-01-03")'
{
  "Name": "Alex",
  "Id": 1,
  "time": "2022-01-01T04:29:18.9099882Z"
}
{
  "Name": "Homer",
  "Id": 2,
  "time": "2022-01-02T04:29:18.9099882Z"
}

Demo

You could also convert the date string into eg Unix time ("seconds since the Epoch") using fromdate and operate on that as a number (after employing sub to cut off second fractions in order to obtain an ISO 8601 compatible date):

jq 'select(.time | sub("\\.\\d+"; "") | fromdate < 1641100000)'
{
  "Name": "Alex",
  "Id": 1,
  "time": "2022-01-01T04:29:18.9099882Z"
}
{
  "Name": "Homer",
  "Id": 2,
  "time": "2022-01-02T04:29:18.9099882Z"
}

Demo

Or, for the sake of another example, using strptime to convert the date into a broken-down array (containing in this order: year, (zero-based) month, day, hour, minute, second, day of week, and day of year) and then filtering eg for Mondays (represented as 1 in that array at the (zero-based) position 6 ):

jq 'select(.time | sub("\\.\\d+"; "") | strptime("%FT%TZ") | .[6] == 1)'
{
  "Name": "Bart",
  "Id": 3,
  "time": "2022-01-03T04:29:18.9099882Z"
}

Demo

A powershell example. Taking the input as an array:

[{
  "Name": "Alex",
  "Id": 1,
  "time": "2022-01-01T04:29:18.9099882Z"
},
{
  "Name": "Homer",
  "Id": 2,
  "time": "2022-01-02T04:29:18.9099882Z"
},
{
  "Name": "Bart",
  "Id": 3,
  "time": "2022-01-03T04:29:18.9099882Z"
}]

For some reason in powershell 5, I have use parentheses to complete the conversion first (could use a lot of memory). The time fields are converted to the.Net [datetime] type, and then it's easy to compare them. The right side of a comparision automatically gets converted to a datetime if it can be.

(get-content file.json | convertfrom-json) | 
foreach-object { $_.time = [datetime]$_.time; $_ } | 
where-object { $_.time -ge '1/1/22' -and $_.time -le '1/2/22' }

Name  Id time
----  -- ----
Homer  2 1/1/2022 11:29:18 PM

Here's a workaround for the original file of consecutive json objects:

get-content file.json -ReadCount 5 | 
foreach-object { $_ | convertfrom-json } | 
foreach-object { $_.time = [datetime]$_.time; $_ } | 
where-object { $_.time -ge '1/1/22' -and $_.time -le '1/2/22' }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM