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:
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
-
jq -r 'last(select(.ip=="'"${TARGET}"'"))' file.json(does not work) -
jq -r 'select(.ip=="'"${TARGET}"'") | .[-1]' file.json(does not work) -
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?
>Solution :
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'
Using -n and inputs:
jq -nr --arg ip '1.1.1.1' 'last(inputs | select(.ip==$ip)).last_scan_date'
Output:
1673152750
Note: Use --arg to introduce external values.