1

I am trying to parse below big json file using bash

//part of json file
{"name": "Jenkins", "version": "Jenkins-2.22"},
{"name": "FitNesse", "version": "FitNesse-2.1"},
{"name": "Quint","version": "Quint-2.12"},
{"name": "Otto","version": "Otto-1.0"},
{"name": "Gradle","version": "Gradle-1.1"}

I am able read the line matching 'version' from json file

while read line; do
  if [[ $line =~ "version" ]] ; then
    echo $line; fi
done < $manifestfile

I want to store the values[Jenkins-2.22, FitNesse-2.1, Quint-2.12, Otto-1.0, Gradle-1.1] in array in my while loop

need help with tweaking my above code

3
  • 2
    Any reason you can't use jq? Commented May 5, 2017 at 18:31
  • is array mandatory? does the array need to processed after all? Commented May 5, 2017 at 18:54
  • yes @RomanPerekhrest all these tools version are displayed in different webpage (ex wiki.tools.com) once I have the version stored in an array then I can pass each array element and run seacrh against my wiki page Commented May 5, 2017 at 19:09

4 Answers 4

3

Assuming that the sample input above is inside a JSON array in file file.json, i.e.:

[
  {"name": "Jenkins", "version": "Jenkins-2.22"},
  {"name": "FitNesse", "version": "FitNesse-2.1"},
  {"name": "Quint","version": "Quint-2.12"},
  {"name": "Otto","version": "Otto-1.0"},
  {"name": "Gradle","version": "Gradle-1.1"}
]

Note: The only change required to make the commands below work in Bash 3.x too is to replace readarray -t versions with IFS=$'\n' read -d '' -ra versions

Using Bash 4.x and jq:

jq must be installed first, but that's well worth the effort, if feasible: it enables sophisticated, robust JSON parsing.

# Extract the version numbers and read them into a Bash array.
readarray -t versions < <(jq -r '.[].version' file.json)

# Print the array.
printf '%s\n' "${versions[@]}"

The above yields:

Jenkins-2.22
FitNesse-2.1
Quint-2.12
Otto-1.0
Gradle-1.1

Using Bash 4.x and awk:

If you cannot install jq, the following awk solution is an alternative, but note that it is much less robust and relies on the JSON to be formatted exactly as above.
This warning applies to any solution using standard utilities (awk, grep, sed, ...) - only a dedicated JSON parser will work robustly.

readarray -t versions < <(awk -F\" 'NF>1 { print $(NF-1) }' file.json)

# Print the array.
printf '%s\n' "${versions[@]}"
Sign up to request clarification or add additional context in comments.

Comments

2
sed -n 's/.*"\([^"]*\)"}.*/\1/p' <file>

Comments

1

jq is a proper tool to manipulate JSON data in Unix shell.

Let's say test.json file contains:

[
{"name": "Jenkins", "version": "Jenkins-2.22"},
{"name": "FitNesse", "version": "FitNesse-2.1"},
{"name": "Quint","version": "Quint-2.12"},
{"name": "Otto","version": "Otto-1.0"},
{"name": "Gradle","version": "Gradle-1.1"}
]

test_json.sh script (simplified version):

#!/bin/bash
versions=$(jq '.[] | .version' test.json)
versions_arr=($versions)  # contains an array of `version` key values

I must warn that the above approach ($versions) (creating an array upon string splitting) may fail if the string $versions has globbing characters in it.


The more "steady" approach would be using built-in read command with -a option to read the data wordwise into the specified array:

test_json.sh script ("steady" version):

#!/bin/bash
versions=$(jq '.[] | .version' test.json)
read -a versions_arr <<< $versions  # read `version` key values into array

Now, versions_arr is an array of version key values.
To print for e.g. the second array value you would do:

echo ${versions_arr[1]} 

The output:

"FitNesse-2.1"

Comments

0

Use JQ for parsing your Json easily, just install JQ, then use :

if you have a json array, and in every element you have the field version, you can use :

 cat myJsonFile | jq '.[].version'

That will return a list of versions

If you want to process line by line use

while read line; do
  if [[ $line =~ "version" ]] ; then
    echo $line | jq .[] | jq ."version" ; fi
done < $manifestfile

Comments

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.