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?
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'
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.