Home > Blockchain >  Unable to get the last object from json using jq
Unable to get the last object from json using jq

Time:01-08

I'm not able to get the last object filtered after using jq select. To demonstrate this issue, I got the following simple json file that contains list of IP addresses:

file.json

{
  "ip": "1.1.1.1",
  "tested_count": 17,
  "last_scan_date": "1673146101"
}
{
  "ip": "1.1.1.1",
  "tested_count": 17,
  "last_scan_date": "1673146107"
}
{
  "ip": "2.2.2.2",
  "tested_count": 17,
  "last_scan_date": "1673146109"
}
{
  "ip": "1.1.1.1",
  "tested_count": 10,
  "last_scan_date": "1673152750"
}
{
  "ip": "1.2.3.4",
  "tested_count": 11,
  "last_scan_date": "1673152755"
}

In order to list out the data for IP 1.1.1.1, I will do the following in bash script:

#!/bin/bash
TARGET="1.1.1.1"
jq -r 'select(.ip=="'"${TARGET}"'")' file.json

The above will output:

{
  "ip": "1.1.1.1",
  "tested_count": 17,
  "last_scan_date": "1673146101"
}
{
  "ip": "1.1.1.1",
  "tested_count": 17,
  "last_scan_date": "1673146107"
}
{
  "ip": "1.1.1.1",
  "tested_count": 10,
  "last_scan_date": "1673152750"
}

Now, what I want is the last output for this IP 1.1.1.1 with the last_scan_date 1673152750 .

So I tried one of these:

  1. jq -r 'select(.ip=="'"${TARGET}"'") | last' file.json (does not work)

I got error:

> jq: error (at file.json:5): Cannot index object with number
> jq: error (at file.json:10): Cannot index object with number
> jq: error (at file.json:20): Cannot index object with number
  1. jq -r 'last(select(.ip=="'"${TARGET}"'"))' file.json (does not work)

  2. jq -r 'select(.ip=="'"${TARGET}"'") | .[-1]' file.json (does not work)

  3. jq -r 'select(.ip=="'"${TARGET}"'") | to_entries | last' file.json (does not work)

The expected output is:

{
  "ip": "1.1.1.1",
  "tested_count": 10,
  "last_scan_date": "1673152750"
}

I searched about this but mostly they are talking about getting the last array but I don't have array here just objects. Can jq actually do this?

CodePudding user response:

You don't need to add arrays brackets beforehand. Either make the input stream an array by using the -s command-line option, and access the items with .[], or use inputs to fetch the items (which requires the -n option). Then, last can give you the preferred item.

Using -s and .[]:

jq -sr --arg ip '1.1.1.1' 'last(.[] | select(.ip==$ip)).last_scan_date'

Demo

Using -n and inputs:

jq -nr --arg ip '1.1.1.1' 'last(inputs | select(.ip==$ip)).last_scan_date'

Demo

Output:

1673152750

Note: Use --arg to introduce external values.

  • Related