1

I have a test.json file which contains below property.

"solr.baseuri":"http://10.201.17.8:80"

We are getting expected output for the below script if we parse the exact variable(solr.baseuri) name using jq command.

Shell script :

#!/bin/bash

key=`solr.baseuri`

value=`cat test.json |jq '."solr.baseuri"' | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"`

echo "solr value is $value"

Output :

solr value is 10.201.17.8

not sure how to use the $key with jq command inside the script to display the value. trying with below command which is not working

value=`cat test.json |jq '."${key}"' | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"`
Nan
  • 13
  • 1
  • 5
  • Are you trying to get rid of the literal quotes in the output? Passing `-r` to `jq` will emit a raw value, which thus doesn't contain them. – Charles Duffy Jul 19 '18 at 18:25

3 Answers3

4

I think you just want to pass the key as an --arg:

jq --arg key "solr.baseuri" '.[$key]' file.json

Testing it out, using the minimal JSON that could be made from the line in your example:

$ cat file.json 
{ "solr.baseuri":"http://10.201.17.8:80" }
$ jq --arg key "solr.baseuri" '.[$key]' file.json 
"http://10.201.17.8:80"

Rather than piping to grep, you might want to consider using jq built-in functionality to parse the part of the string that you're interested in.

To extract the host to a variable, you could use capture:

$ value=$(jq --arg key solr.baseuri -r '.[$key] | capture(".*://(?<host>[^:]+)") | .host' file.json)
$ echo "$value"
10.201.17.8

This assumes that the property always is of the form scheme://host, optionally followed by :port.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
2

You can do everything in jq alone. You can probably do it better than the following, even:

#!/usr/bin/env bash

key="solr.baseuri"
jq --arg key "$key" '
  .[$key] | split("/") | .[2] | split(":") | .[0]' test.json

This uses the shell variable $key as an argument to jq. Jq then splits the resultant URL, first on forward slash, then on colon. The result should be the hostname (or in the case of your sample data, the IP address).

Note that in your initial script, you had a quoting problem -- your variable assignment used backquotes, which are an obsolete mechanism to handle command substitution. Double or single quotes are used for strings. You probably already know that by now. ;-)

peak
  • 105,803
  • 17
  • 152
  • 177
ghoti
  • 45,319
  • 8
  • 65
  • 104
1

Your script has multiple problems. The quick and dirty answer is "use double quotes" but in addition, you need to fix your hideous syntax errors.

#!/bin/bash
# single quotes '...' not backticks `...`
key='solr.baseuri'
# avoid useless cat
# prefer modern $(...) syntax over paleolithic `...`
# use double quotes around variable
value=$(jq ".\"$key\"" test.json | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b")

echo "solr value is $value"

It should not be hard to avoid the grep (and perhaps even also the echo) and use jq to extract just the IP address from the URL, either. (\b is not valid in most grep versions anyway.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • https://github.com/stedolan/jq/issues/537 suggests using a regex capture, though it will be slightly hairy. If you know it's always a HTTP URL with a numeric IP address, your `grep` regex won't be hard to adapt. – tripleee Jul 19 '18 at 12:42
  • https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable has the spiel on shell quoting. – tripleee Jul 19 '18 at 12:44
  • See also http://shellcheck.net/ which can help diagnose at least some of these problems. – tripleee Jul 19 '18 at 15:08