code-8
code-8

Reputation: 58632

Create variables base on cURL response - Bash

I'm trying to create 2 variables via bash $lat, $long base on the result of my curl response.

curl ipinfo.io/33.62.137.111 | grep "loc" | awk '{print $2}'

I got.

"42.6334,-71.3162",

I'm trying to get

Can someone give me a little push ?

Upvotes: 0

Views: 165

Answers (2)

Léa Gris
Léa Gris

Reputation: 19545

IFS=, read -r lat long < <(
  curl -s ipinfo.io/33.62.137.111 |
    jq -r '.loc'
)

printf 'Latitude is: %s\nLongitude is: %s\n' "$lat" "$long"

The ipinfo.io API is returning JSON data, so let parse it with jq:

Here is the JSON as returned by the query from your sample:

{
  "ip": "33.62.137.111",
  "city": "Columbus",
  "region": "Ohio",
  "country": "US",
  "loc": "39.9690,-83.0114",
  "postal": "43218",
  "timezone": "America/New_York",
  "readme": "https://ipinfo.io/missingauth"
}

We are going to JSON query the loc entry from the main root object ..

  • curl -s ipinfo.io/33.62.137.111: download the JSON data -s silently without progress.
  • jq -r '.loc': Process JSON data, query the loc entry of the main object and -r output raw string.
  • IFS=, read -r lat long < <(: Sets the Internal Field Separator to , and read both lat and long variables from the following command group output stream.

Upvotes: 4

Kenan G&#252;ler
Kenan G&#252;ler

Reputation: 1993

Although the answer from @LeaGris is quite interesting, if you don't want to use an external library or something, you can try this:

Playground: https://repl.it/repls/ThoughtfulImpressiveComputer

coordinates=($(curl ipinfo.io/33.62.137.111 | sed 's/ //g' | grep -P '(?<=\"loc\":").*?(?=\")' -o | tr ',' ' '))

echo "${coordinates[@]}"

echo ${coordinates[0]}
echo ${coordinates[1]}

Example output:

39.9690 -83.0114 # echo "${coordinates[@]}"
39.9690 # ${coordinates[0]}
-83.0114 # ${coordinates[1]}

Explanation:

  1. curl ... get the JSON data

  2. sed 's/ //g' remove all spaces

  3. grep -P ... -o

    • -P interpret the given pattern as a perl regexp
    • (?<=\"loc\":").*?(?=\")
      • (?<=\"loc\":") regex lookbehind
      • .*? capture the longitude and latitude part with non-greedy search
      • (?=\") regex lookahead
    • -o get only the matching part which'ld be e.g. 39.9690,-83.0114
  4. tr ',' ' ' replace , with space

  5. Finally we got something like this: 39.9690 -83.0114

Putting it in parentheses lets us create an array with two values in it (cf. ${coordinates[...]}).

Upvotes: 1

Related Questions