3

I am trying my hand on shell scripting and was trying to extract values from a Json and store it into a variable to use it later. But I am unable to do so, have tried follow up lots of links and suggestion, probably I am doing something wrong. Basically I am using curl to hit an url and from the response I am trying to extract the value of a status field . I am trying the following lines,

result=$(curl "http://localhost:9200/domains" | grep "status" | awk '{print $1 }') echo "the result is" $result

The curl command will fetch something like

{"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"domains","index_uuid":"_na_","index":"domains"}],"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"domains","index_uuid":"_na_","index":"domains"},"status":404}

Any help in this regard is really appreciated. I know we can do it in jq or perl but I am looking for a solution using grep, sed or awk.

Thanks Ashit

Ashit_Kumar
  • 601
  • 2
  • 10
  • 28
  • 4
    Choose the right tool first. I suggest to use [jq](https://stackoverflow.com/tags/jq/info). – Cyrus Jun 09 '18 at 11:08
  • 1
    grep, sed and awk are not made to operate on structured data like JSON, so anything you build based on these tools will be very brittle. It'll break, for example, when someone changes the formatting of the input data, and nobody expects their JSON tools to break when that happens. `jq .status` is the way to go here. – Wintermute Jun 09 '18 at 12:02

3 Answers3

5

Using grep and awk

result=$(curl "http://localhost:9200/domains" | \
    grep -o -E "\"status\":[0-9]+" | awk -F\: '{print $2}')
  1. First, use grep to extract the pattern status:[0-9]+
  2. Then, use awk to split the result by : and print the second field
Lee HoYo
  • 1,217
  • 9
  • 9
  • 1
    You never need grep when you're using awk since awk can do anything useful that grep can do. Any `grep ... | awk ...` pipline can be written as a single awk command, e.g. your code could be written in GNU awk as `awk 'match($0,/\"status\":([0-9]+)/,a){print a[1]}'` – Ed Morton Jun 10 '18 at 11:59
0

When you are sure status won't pop up on a different place in your data, and always a numeric status, you can try

result=$(curl "http://localhost:9200/domains" | \
    sed -rn 's/.*,"status":([0-9]*).*/\1/p')

Use -E if there is no option -r

Walter A
  • 19,067
  • 2
  • 23
  • 43
0

Given that single sample of input, all you'd need is:

curl '...' | awk -F'[:}]' '{print $(NF-1)}'

If that's NOT all you need then edit your question to clarify your requirements and provide more truly representative sample input and expected output.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185