Eric B.
Eric B.

Reputation: 24411

Sort / filter multiple objects in JQ by date

I'm trying to use JQ to find the most recent artifact in a Nexus API query. Right now, my JSON output looks something like:

{
  "items" : [ {
    "downloadUrl" : "https://nexus.ama.org/repository/Snapshots/org/sso/browser-manager/1.0-SNAPSHOT/browser-manager-1.0-20180703.144121-1.jar",
    "path" : "org/sso/browser-manager/1.0-SNAPSHOT/browser-manager-1.0-20180703.144121-1.jar",
    "id" : "V0FEQS1TbmFwc2hvdHM6MzhjZDQ3NTQwMTBkNGJhOTY1N2JiOTEyMTM1ZGRjZWQ",
    "repository" : "Snapshots",
    "format" : "maven2",
    "checksum" : {
      "sha1" : "7ac324905fb1ff15ef6020f256fcb5c9f54113ca",
      "md5" : "bb25c483a183001dfdc58c07a71a98ed"
    }
  }, {
    "downloadUrl" : "https://nexus.ama.org/repository/Snapshots/org/sso/browser-manager/1.0-SNAPSHOT/browser-manager-1.0-20180703.204941-2.jar",
    "path" : "org/sso/browser-manager/1.0-SNAPSHOT/browser-manager-1.0-20180703.204941-2.jar",
    "id" : "V0FEQS1TbmFwc2hvdHM6MzhjZDQ3NTQwMTBkNGJhOWM4YjQ0NmRjYzFkODkxM2U",
    "repository" : "Snapshots",
    "format" : "maven2",
    "checksum" : {
      "sha1" : "b4ba2049ea828391c720f49b6668a66a8b0bca9c",
      "md5" : "6757c55c0e6d933dc90e398204cca966"
    }
  } ],
  "continuationToken" : null
}

I've managed to use JQ to repackage the data as:

.items[] | { "id" : .id,  "date" : (.path |  scan("[0-9]{8}\\.[0-9-]*")) } 

output:

{
  "id": "V0FEQS1TbmFwc2hvdHM6MzhjZDQ3NTQwMTBkNGJhOTY1N2JiOTEyMTM1ZGRjZWQ",
  "date": "20180703.144121-1"
}
{
  "id": "V0FEQS1TbmFwc2hvdHM6MzhjZDQ3NTQwMTBkNGJhOWM4YjQ0NmRjYzFkODkxM2U",
  "date": "20180703.204941-2"
}

Now I'm a little stuck trying to figure out which of the two JSON objects is the most recent. How can I sort by date and extract the id for that object?

Is there a better way to filter/sort this data? My example has only 2 items[] in the JSON response, but there may be a larger number of them.

Upvotes: 0

Views: 2391

Answers (1)

peak
peak

Reputation: 116770

The filter sort_by/1 will sort your timestamps in chronological order, but it requires an array as input, so you could write:

.items 
| map({ "id" : .id,  "date" : (.path |  scan("[0-9]{8}\\.[0-9-]*")) })
| sort_by(.date)
| .[-1]

The trailing .[-1] selects the last item, so with your input the result would be:

{
  "id": "V0FEQS1TbmFwc2hvdHM6MzhjZDQ3NTQwMTBkNGJhOWM4YjQ0NmRjYzFkODkxM2U",
  "date": "20180703.204941-2"
}

Upvotes: 1

Related Questions