4

I have a json file names test.json with the below content.

{
        "run_list": ["recipe[cookbook-ics-op::setup_server]"],
    "props": {
        "install_home": "/test/inst1",
            "tmp_dir": "/test/inst1/tmp",
        "user": "tuser
                 }
}

I want to read this file into a variable in shell script & then extract the values of install_home,user & tmp_dir using expr. Can someone help, please?

props=cat test.json

works to get the json file into a variable. Now how can I extract the values using expr. Any help would be greatly appreciated.

3
  • Don't use expr or regular expressions (anticipating some nasty regex-based answers). Use a proper JSON parser such as jq. Commented Nov 5, 2015 at 14:11
  • The sample JSON supplied is malformed, it's missing a closing double quote on the line that says tuser. Commented May 25, 2018 at 4:03
  • Possible duplicate of stackoverflow.com/questions/1955505/… Commented Jul 12, 2021 at 1:52

4 Answers 4

5

Install jq

yum -y install epel-release
yum -y install jq

Get the values in the following way

install_home=$(cat test.json  | jq -r '.props.install_home')
tmp_dir=$(cat test.json  | jq -r '.props.tmp_dir')
user=$(cat test.json  | jq -r '.props.user')
Sign up to request clarification or add additional context in comments.

Comments

4

jq is a dedicated parser for JSON files. Install jq.

values in the json can be retrieved as:

jq .<top-level-attr>.<next-level-attr> <json-file-path>

if JSON contains an array

jq .<top-level-attr>.<next-level-array>[].<elem-in-array> <json-file-path>

if you want a value in a shell variable

id = $(jq -r .<top-level-attr>.<next-level-array>[].<next-level-attr> <json-file-path>)

echo id

use -r if you need unquoted value

Comments

3

For a pure bash solution I suggest this:
github.com/dominictarr/JSON.sh
It could be used like this:

./json.sh -l -p < example.json  

print output like:

["name"]        "JSON.sh"
["version"]     "0.2.1"
["description"] "JSON parser written in bash"
["homepage"]    "http://github.com/dominictarr/JSON.sh"
["repository","type"]   "git"
["repository","url"]    "https://github.com/dominictarr/JSON.sh.git"
["bin","JSON.sh"]       "./JSON.sh"
["author"]      "Dominic Tarr <[email protected]> (http://bit.ly/dominictarr)"
["scripts","test"]      "./all-tests.sh"

From here is pretty trivial achive what you are looking for

Comments

1

For simple JSON, it may be treated as a plain text file. In that case, we can use simple text pattern matching to extract the information we need.

If you observe the following lines:

    "install_home": "/test/inst1",
        "tmp_dir": "/test/inst1/tmp",
    "user": "user"

There exists a pattern on each line that can be described as key and value:

  • "key" : "value"

We can use perl with regular expressions to exact the value for any given key:

  • "key" hardcoded for each case "install_home", "tmp_dir" and "user"
  • "value" as (.*) regular expression

Then we use the $1 matching group to retrieve the value.

i=$(perl -ne 'if (/"install_home": "(.*)"/) { print $1 . "\n" }' test.json)
t=$(perl -ne 'if (/"tmp_dir": "(.*)"/) { print $1 . "\n" }' test.json)
u=$(perl -ne 'if (/"user": "(.*)"/) { print $1 . "\n" }' test.json)

cat <<EOF
install_home: $i
tmp_dir     : $t
user        : $u
EOF

Which outputs:

install_home: /test/inst1
tmp_dir     : /test/inst1/tmp
user        : tuser

1 Comment

While this might work for a simple json, for more complex json using regex will be a nightmare!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.