1

Is it possible to use array values as variables? For example, i have this script:

#!/bin/bash
SOURCE=$(curl -k -s $1 | sed 's/{//g;s/}//g;s/,/"\n"/g;s/:/=/g;s/"//g' | awk -F"=" '{ print $1 }')
JSON=$(curl -k -s $1 | sed 's/{//g;s/}//g;s/,/"\n"/g;s/:/=/g;s/"//g' | awk -F"=" '{ print $NF }')
data=$2
readarray -t prot_array <<< "$SOURCE"
readarray -t pos_array <<< "$JSON"

for ((i=0; i<${#prot_array[@]}; i++)); do
echo  "${prot_array[i]}" "${pos_array[i]}" | sed 's/NOK/0/g;s/OK/1/g' | grep $2 | awk -F' ' '{ print $2,$3,$4 }'
done

EDIT:

I just added: grep $2 | awk -F' ' '{ print $2,$3,$4 }'

Usage:

./json.sh URL

Sample (very short) output:

DATABASE 1
STATUS 1

I don't want to echo out all the lines, i would like to use DATABASE STATUS as variable $DATABASE and echo that out. I just need DATABASE (or any other) value from command line. Is it somehow possible to use something like this?

./json.sh URL $DATABASE

Happy to explain more if needed.

EDIT: curl output without any formattings etc:

{  
   "VERSION":"R3.1",
   "STATUS":"OK",
   "DATABASES":{  
      "READING":"OK"
   },
   "TIMESTAMP":"2017-03-08-16-20-35"
} 

Output using script:

VERSION R3.1 
STATUS 1 
DATABASES 1 
TIMESTAMP 2017-03-08-16-21-54 

What i want is described before. For example use DATABASE as varible $DATABASE and somehow get the value "1"

EDIT:

Random json from uconn.edu

./json.sh https://github.uconn.edu/raw/nam12023/novaLauncher/master/manifest.json

Another:

./json.sh https://gitlab.uwe.ac.uk/dc2-roskilly/angular-qs/raw/master/.npm/nan/2.4.0/package/package.json

Last output begins with:

name nan
version 2.4.0

From command line: ./json.sh URL version

At leats it works for me.

9
  • Why can't you use a proper JSON parser for processing json output from cURL? instead of sed? It makes your task a lot simpler. Commented Mar 8, 2017 at 14:15
  • 1
    Please post your output from curl and the exact output you are looking to get Commented Mar 8, 2017 at 14:16
  • 1
    Please update it as part of the question and remove it from the comments Commented Mar 8, 2017 at 14:28
  • So OK corresponds to 1, is it? How is your expected output generated? Commented Mar 8, 2017 at 14:34
  • Where does the version number R13.1369 come from? (The timestamps in your input and output don't match either, so I suspect you aren't showing the output for the given input.) Commented Mar 8, 2017 at 14:40

1 Answer 1

5

I think you want to use jq something like this:

$ curl -k -s "$1" | jq --arg d DATABASES -r '
    "VERSION \(.VERSION)",
    "STATUS \(if .STATUS == "OK" then 1 else 0 end)",
    "DATABASES \(if .[$d].READING == "OK" then 1 else 0 end)", 
    "TIMESTAMP \(.TIMESTAMP)"
'
VERSION R3.1
STATUS 1
DATABASES 1
TIMESTAMP 2017-03-08-16-20-35

(I'm probably missing a simpler way to convert a boolean value to an integer.)

Quick explanation:

  1. The ,-separated strings each become a separate output line.
  2. The -r option outputs a raw string, rather than a JSON string value.
  3. The name of the database field is passed using the --arg option.
  4. \(...) is jq's interpolation operator; the contents are evaluated as a JSON expression and the result is inserted into the string.
Sign up to request clarification or add additional context in comments.

8 Comments

Oddly enough, you don't, but putting the space there is a good idea anyway.
Good answer. Just a side note: You don't need to build a list using [ ] and then join("\n") at the end. Just separate individual filters by ,. jq will print the results of them by default on a separate line(s).
So, the output is the same. Good, but i need to assing DATABASE somehow as variable. Or any other first sting in a output. P.S behind my URL could be much longer json. At the moment i was testing my script agains another json, much longer, different output lines etc. Output basically is in same format: "SOMESTING somevalue"
DATABASE is passed as a variable, assuming it is always a key mapping to another object with a READING key. It can be generalized further, but you're going to have to be clearer about what other inputs you might see. (Or are you just saying that the output should use the same string that is input?)
@hek2mgl I started with a multiline string, then broke it into the form shown for readability. I did forget just using a list of separate filters, though.
|

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.