How to use jq when the response is not a list - jq

My json response is like this.
{
"level": "info",
"timestamp": "2022-03-21T16:10:27.060Z",
"msg": "starting test",
}
{
"level": "warn",
"timestamp": "2022-03-21T16:10:27.060Z",
"msg": "message 2"
}
{
"level": "error",
"timestamp": "2022-03-21T16:10:27.060Z",
"msg": "message 3"
}
I want to extract.
Either 3rd message (or nth message) or the message associated with error
How can I do this with jq?

Use select to filter by condition
jq 'select(.level == "error")'
{
"level": "error",
"timestamp": "2022-03-21T16:10:27.060Z",
"msg": "message 3"
}
Demo
To extract the message, use the -r option
jq -r 'select(.level == "error").msg'
message 3
Demo
If you want to access the nth object, you may want to use a structure whose items you can count. Using the -s option would turn the input stream into an array. Using the --argjson option enables you using an external (JSON) value for reference:
jq -sr --argjson n 2 '.[$n].msg'
message 3
Demo
To directly address the nth element of a stream, use the nth function, in combination with inputs and the -n option to address the entire stream at once:
jq -nr --argjson n 2 'nth($n;inputs).msg'
message 3
Demo

Related

How to get the value using jq command?

How to get the value of filecode in
"{"msg": "OK", "status": 200, "files": [ { "filecode":"am9kb3tw6hv1", "filename": "video.mp4", "status": "OK" } ]}"
The printed output will be
am9kb3tw6hv1
I supposed your file name is test.json
echo {\"msg\": \"OK\", \"status\": 200, \"files\": [ { \"filecode\":\"am9kb3tw6hv1\", \"filename\": \"video.mp4\", \"status\": \"OK\" } ]} > test.json
Run this
jq '.files[0].filecode' test.json
Output
"am9kb3tw6hv1"
If you don't want the quotes, then use -r
jq -r '.files[0].filecode' test.json
output
am9kb3tw6hv1
I found this page that explain how to use jq

How to use jq package to parse name and id from json?

I have an output that i am getting in this format :-
[
{
"_class": "hudson.model.FreeStyleProject",
"name": "my-name",
"id": "123"
},
{
"_class": "hudson.model.FreeStyleProject",
"name": "my-name2",
"id": "456"
},
{
"_class": "hudson.model.FreeStyleProject",
"name": "my-name3",
"id": "789"
}
]
How can i parse the name and id using jq?
I tried to use [].name
but i get curl: (23) Failed writing body (320 != 1338)
Any help will be appreciated. Thank you.
You failed to mention the relevant error:
jq: error (at <stdin>:17): Cannot index array with string "name"
The program should be
.[].name
Because you provided an incorrect program to jq, it exited earlier than it normally would. This caused the pipe between curl and jq to close, which cause curl to become unable to write to the pipe, which caused curl to emit the error message you did provide.
Demo
https://jqplay.org/s/nolGbk3sD1
Use filter
.[] | .name, .id

Transforming json to table using JQ gives "Cannot index string error"

Output of the following command
jq '.data[] | select(.vulnerable_configuration_cpe_2_2 | contains(["2.4.38"]))' search1.json
gives me
{
"Modified": "2019-06-11T17:29:00.647000",
"Published": "2019-06-11T17:29:00.630000",
"cvss": "5.0",
"cwe": "CWE-399",
"id": "CVE-2019-0220",
"last-modified": "2019-06-25T06:15:10.627000",
"reason": "Text search",
"references": [
"http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00051.html"
],
"summary": "A vulnerability was found in Apache HTTP Server 2.4.0 to 2.4.38. When the path component of a request URL contains multiple consecutive slashes ('/'), directives such as LocationMatch and RewriteRule must account for duplicates in regular expressions while other aspects of the servers processing will implicitly collapse them.",
"vulnerable_configuration": [
"cpe:2.3:a:apache:http_server:2.4.0",
"cpe:2.3:a:apache:http_server:2.4.1",
"cpe:2.3:a:apache:http_server:2.4.2",
"cpe:2.3:a:apache:http_server:2.4.3",
"cpe:2.3:a:apache:http_server:2.4.4",
"cpe:2.3:a:apache:http_server:2.4.6",
"cpe:2.3:a:apache:http_server:2.4.7",
"cpe:2.3:a:apache:http_server:2.4.8",
"cpe:2.3:a:apache:http_server:2.4.9",
"cpe:2.3:a:apache:http_server:2.4.10",
"cpe:2.3:a:apache:http_server:2.4.12",
"cpe:2.3:a:apache:http_server:2.4.14",
"cpe:2.3:a:apache:http_server:2.4.16",
"cpe:2.3:a:apache:http_server:2.4.17",
"cpe:2.3:a:apache:http_server:2.4.18",
"cpe:2.3:a:apache:http_server:2.4.19",
"cpe:2.3:a:apache:http_server:2.4.20",
"cpe:2.3:a:apache:http_server:2.4.21",
"cpe:2.3:a:apache:http_server:2.4.22",
"cpe:2.3:a:apache:http_server:2.4.23",
"cpe:2.3:a:apache:http_server:2.4.24",
"cpe:2.3:a:apache:http_server:2.4.25",
"cpe:2.3:a:apache:http_server:2.4.26",
"cpe:2.3:a:apache:http_server:2.4.27",
"cpe:2.3:a:apache:http_server:2.4.28",
"cpe:2.3:a:apache:http_server:2.4.29",
"cpe:2.3:a:apache:http_server:2.4.30",
"cpe:2.3:a:apache:http_server:2.4.32",
"cpe:2.3:a:apache:http_server:2.4.33",
"cpe:2.3:a:apache:http_server:2.4.34",
"cpe:2.3:a:apache:http_server:2.4.35",
"cpe:2.3:a:apache:http_server:2.4.36",
"cpe:2.3:a:apache:http_server:2.4.37",
"cpe:2.3:a:apache:http_server:2.4.38",
"cpe:2.3:o:opensuse:leap:15.0",
"cpe:2.3:o:opensuse:leap:42.3",
"cpe:2.3:o:debian:debian_linux:8.0",
"cpe:2.3:o:debian:debian_linux:9.0",
"cpe:2.3:o:fedoraproject:fedora:28",
"cpe:2.3:o:fedoraproject:fedora:29",
"cpe:2.3:o:fedoraproject:fedora:30",
"cpe:2.3:o:canonical:ubuntu_linux:14.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:16.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:18.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:18.10"
],
"vulnerable_configuration_cpe_2_2": [
"cpe:/a:apache:http_server:2.4.0",
"cpe:/a:apache:http_server:2.4.1",
"cpe:/a:apache:http_server:2.4.2",
"cpe:/a:apache:http_server:2.4.3",
"cpe:/a:apache:http_server:2.4.4",
"cpe:/a:apache:http_server:2.4.6",
"cpe:/a:apache:http_server:2.4.7",
"cpe:/a:apache:http_server:2.4.8",
"cpe:/a:apache:http_server:2.4.9",
"cpe:/a:apache:http_server:2.4.10",
"cpe:/a:apache:http_server:2.4.12",
"cpe:/a:apache:http_server:2.4.14",
"cpe:/a:apache:http_server:2.4.16",
"cpe:/a:apache:http_server:2.4.17",
"cpe:/a:apache:http_server:2.4.18",
"cpe:/a:apache:http_server:2.4.19",
"cpe:/a:apache:http_server:2.4.20",
"cpe:/a:apache:http_server:2.4.21",
"cpe:/a:apache:http_server:2.4.22",
"cpe:/a:apache:http_server:2.4.23",
"cpe:/a:apache:http_server:2.4.24",
"cpe:/a:apache:http_server:2.4.25",
"cpe:/a:apache:http_server:2.4.26",
"cpe:/a:apache:http_server:2.4.27",
"cpe:/a:apache:http_server:2.4.28",
"cpe:/a:apache:http_server:2.4.29",
"cpe:/a:apache:http_server:2.4.30",
"cpe:/a:apache:http_server:2.4.32",
"cpe:/a:apache:http_server:2.4.33",
"cpe:/a:apache:http_server:2.4.34",
"cpe:/a:apache:http_server:2.4.35",
"cpe:/a:apache:http_server:2.4.36",
"cpe:/a:apache:http_server:2.4.37",
"cpe:/a:apache:http_server:2.4.38",
"cpe:/o:opensuse:leap:15.0",
"cpe:/o:opensuse:leap:42.3",
"cpe:/o:debian:debian_linux:8.0",
"cpe:/o:debian:debian_linux:9.0",
"cpe:/o:fedoraproject:fedora:28",
"cpe:/o:fedoraproject:fedora:29",
"cpe:/o:fedoraproject:fedora:30",
"cpe:/o:canonical:ubuntu_linux:14.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:16.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:18.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:18.10"
]
}
{
"Modified": "2019-04-08T17:29:00.860000",
"Published": "2019-04-08T17:29:00.843000",
"cvss": "6.0",
"cwe": "CWE-362",
"id": "CVE-2019-0217",
"last-modified": "2019-05-13T23:29:03.847000",
"reason": "Text search",
"references": [
"http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00051.html"
],
"summary": "In Apache HTTP Server 2.4 release 2.4.38 and prior, a race condition in mod_auth_digest when running in a threaded server could allow a user with valid credentials to authenticate using another username, bypassing configured access control restrictions.",
"vulnerable_configuration": [
"cpe:2.3:a:apache:http_server:2.4.38",
"cpe:2.3:o:debian:debian_linux:8.0",
"cpe:2.3:o:debian:debian_linux:9.0",
"cpe:2.3:o:fedoraproject:fedora:29",
"cpe:2.3:o:fedoraproject:fedora:30",
"cpe:2.3:o:canonical:ubuntu_linux:12.04:-:-:-:esm",
"cpe:2.3:o:canonical:ubuntu_linux:14.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:16.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:18.04:-:-:-:lts",
"cpe:2.3:o:canonical:ubuntu_linux:18.10",
"cpe:2.3:o:redhat:enterprise_linux:7.0",
"cpe:2.3:o:opensuse:leap:15.0",
"cpe:2.3:o:opensuse:leap:42.3"
],
"vulnerable_configuration_cpe_2_2": [
"cpe:/a:apache:http_server:2.4.38",
"cpe:/o:debian:debian_linux:8.0",
"cpe:/o:debian:debian_linux:9.0",
"cpe:/o:fedoraproject:fedora:29",
"cpe:/o:fedoraproject:fedora:30",
"cpe:/o:canonical:ubuntu_linux:12.04::~~esm~~~",
"cpe:/o:canonical:ubuntu_linux:14.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:16.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:18.04::~~lts~~~",
"cpe:/o:canonical:ubuntu_linux:18.10",
"cpe:/o:redhat:enterprise_linux:7.0",
"cpe:/o:opensuse:leap:15.0",
"cpe:/o:opensuse:leap:42.3"
]
}
I just want to display all the possible fields in a simple table on the command line but I am not able to achieve it.
I tried the following command
echo $(jq '.data[] | select(.vulnerable_configuration_cpe_2_2 | contains(["2.4.38"]))' search1.json) | jq -r '.[] | "\(.summary)"'
but it gives me error
jq: error (at <stdin>:1): Cannot index string with string "summary"
I already researched about this and tried modifying this command but it sometimes gives me compilation error. I am sure I am making very stupid mistake somewhere
Expected Output
ID CWE CVSS Summary
xyz xyz xyz xyzxyzxyz
I figured it out myself
The correct command is
echo $(jq '.data[] | select(.vulnerable_configuration_cpe_2_2 | contains(["2.4.38"]))' search1.json) | jq -r '. | "\(.summary)"'
After jq -r there should be a . and not .[]

jq: pass variable argument to be used as filter [duplicate]

This question already has answers here:
jq: pass string argument without quotes
(3 answers)
Closed 4 years ago.
How do I pass a variable argument to JQ program that will be used as a filter. Since by default --arg passes the argument as a a string wrapped with quotes the same cannot be used to apply a filter.
here is the JQ program that finds a particular path in the given json and adds a static key value to that path but doesn't work because of the quotes issue.
--argjson name '{ "pattern": "XYZ"}' 'def p: "." + (paths | select(.[-1] == "p-enum") | .[0:-1] | join(".")) ; .|p += $name' sample.json
here is the sample json
{
"type": "object",
"description": "Contains information.",
"properties": {
"type": {
"description": "Type.",
"type": "string",
"p-enum": [
{
"value": "IND",
"description": "Ind."
},
{
"value": "PROP",
"description": "Prop."
}
]
}
}
}
Based on how I interpreted how you were using jq in your other question, it depends on how complicated your filter will be. Any argument that is to be interpreted by jq is not the way you should approach it. This is the equivalent of using eval() and is not only unsupported, but just not a good way to approach this.
If you're simply accessing a property of the input, you have a couple of ways using simple indexing or using getpath/1 for nested paths.
# indexing
# { "properties": ... }
$ jq --arg p 'properties' '.[$p]' input.json
# using getpath
# { "foo": { "bar": ... } }
$ jq --argjson path '["foo","bar"]' 'getpath($path)' input.json

Selecting different keys based on success of failure of curl request

I have the following output from a curl request which can differ based on success / failure of the request
Success:
{
"name": "appId (xxxxx-xxx-1234)",
"sent": 7939246,
"received": 6673490,
"details": [
{
"timestamp": "20180201000041",
"sentbytes": 1805,
"receivedbytes": 1485
}
]}
Failure:
{
"error": "Not found"
}
Can someone let me know how to check whether sent or error exists. I have tried
jq '. | select (.error | .sent)
but that does not seem to be the correct syntax.
Even shorter (no need for additional pipes):
jq '.sent or .error'
The output:
true
You were close.
jq '. | select(.error or .sent)'

Resources