1

I am trying to merge two different JSON strings from STDIN (using pipe, not files) using jq command. Here's the command trying:

curl  ipinfo.io api.ipify.org/?format=json 2>/dev/null | jq -s

Output:

[
  {
    "ip": "139.162.244.103",
    "hostname": "businessproservices.com",
    "city": "London",
    "region": "England",
    "country": "GB",
    "loc": "51.5142,-0.0931",
    "postal": "EC2V",
    "org": "AS63949 Linode, LLC"
  }
]
{
  "ip": "139.162.244.103"
}

Expected output:

{
    "ip": "139.162.244.103",
    "hostname": "businessproservices.com",
    "city": "London",
    "region": "England",
    "country": "GB",
    "loc": "51.5142,-0.0931",
    "postal": "EC2V",
    "org": "AS63949 Linode, LLC"
}
  • 1
    You can't have multiple identical keys in a JSON object. Also, from jq -s you would get a single array with two entries, not an array and an object. – Kusalananda Apr 2 at 12:50
  • @Kusalananda Oh sorry, I have edited the question, thanks – Pradeep Apr 2 at 12:52
  • curl ipinfo.io | jq will return expected output. – pLumo Apr 2 at 12:53
  • Can you confirm that you don't get a single array as output from your jq -s command? jq -s should return [ {...}, {...} ], not [ {...} ] {...} (which is what you are showing). – Kusalananda Apr 2 at 13:34
  • 1
    @Kusalananda it's working perfectly with jq-1.6 :-) Thanks a lot. – Pradeep Apr 2 at 15:24
2

Your curl command queries two hosts. Each will return a JSON document. jq -s will add these together as two entries in an array. To get the first entry (which is what you're presenting as the expected output), simply request .[0] from jq, as in

curl -s ipinfo.io 'api.ipify.org/?format=json' | jq -s '.[0]'

or just use the first host from the start:

curl ipinfo.io

To actually merge the two document, apply the jq command add to the returned list:

curl -s ipinfo.io 'api.ipify.org/?format=json' | jq -s 'add'

Note that since a JSON object can't contain multiple keys with the same name, any later key will replace an equivalent earlier key, so that if your jq -s document is

[
  {
    "ip": "139.162.244.103",
    "hostname": "businessproservices.com",
    "city": "London",
    "region": "England",
    "country": "GB",
    "loc": "51.5142,-0.0931",
    "postal": "EC2V",
    "org": "AS63949 Linode, LLC"
  },
  {
    "ip": "39.62.44.1",
    "country": "UK"
  }
]

then this would be merged as

{
  "ip": "39.62.44.1",
  "hostname": "businessproservices.com",
  "city": "London",
  "region": "England",
  "country": "UK",
  "loc": "51.5142,-0.0931",
  "postal": "EC2V",
  "org": "AS63949 Linode, LLC"
}
  • Is this solution working for you? I had tried this but doesn't work for me, my jq version is jq-1.5-1-a5b5cbe – Pradeep Apr 2 at 13:20
  • @Pradeep With jq -s 'add'? Yes, it works for me using jq 1.6. I can't unfortunately test with an earlier version easily. – Kusalananda Apr 2 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.