Skip to content

Instantly share code, notes, and snippets.

@cjus
Created June 26, 2011 17:42
Show Gist options
  • Save cjus/1047794 to your computer and use it in GitHub Desktop.
Save cjus/1047794 to your computer and use it in GitHub Desktop.
Extract a JSON value from a BASH script
#!/bin/bash
function jsonval {
temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $prop`
echo ${temp##*|}
}
json=`curl -s -X GET http://twitter.com/users/show/$1.json`
prop='profile_image_url'
picurl=`jsonval`
`curl -s -X GET $picurl -o $1.png`
@bcopos
Copy link

bcopos commented Jul 31, 2015

I think sed grouping could also be used, something like:

echo $json | sed 's/{.*$key":"*\([0-9a-zA-Z]*\)"*,*.*}/\1/'

And you can probably tweak it so the grouping regex is just .* instead of [0-9a-zA-Z]*

@evandrix
Copy link

evandrix commented Aug 6, 2015

@ilovefood2
Copy link

hello,

i tried but it only return one instance value, my json file has multiple values under same prop names (play_url)
how can i print all of them?

thanks

@boomshadow
Copy link

I found this Github project incredibly useful for JSON parsing:
https://github.com/trentm/json

@jfig
Copy link

jfig commented Jan 12, 2016

Thanks for this, saved my day ;)

@xianlin
Copy link

xianlin commented Jan 23, 2016

I have the same issue as @ikelca mentioned, any solutions by using this script?

@behelit
Copy link

behelit commented Apr 28, 2016

none of these solutions work for a json response that includes a URL (i.e: https://some.url")

{"response":{"code":"200","message":"OK"},"item":"https://someurl.com/api/"}

@pmckelvy1
Copy link

works great, thanks

@chenqiangzhishen
Copy link

great, thx.

@ggupta01
Copy link

Hi,

if i have a json file or json string, and then i need to extract all the key from it, then what changes i need to do?

thanks in advance.

@ORESoftware
Copy link

gnar gnar

@otherpirate
Copy link

Genius, thanks

@EricW1970
Copy link

Great tips and examples, saved the evening :)... Thanks!

@amedee
Copy link

amedee commented Apr 27, 2018

Or just use jq...

@frazras
Copy link

frazras commented May 6, 2018

jq is that bomb

@i3laze
Copy link

i3laze commented May 10, 2018

@itstayyab,
Your function jsonValue() works pretty great, but only in Bash! Cause For is not supported in Shell.
Could you please rewrite it with a While loop?

@psmanek
Copy link

psmanek commented Aug 4, 2018

Small modification to display only one result for our $KEY.

awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -e 's/^[[:space:]]*//'

But... How to display whole result if it contains "," or ":" character?

@joshimanish1986
Copy link

@psmanek. I am facing similar issue. my value string contains , and =. Please let me know if you or anyone on this thread were able to resolve this.

@the-lazy-fox
Copy link

If my json contains a list of object, how can I extract 2 properties of each object?
Want to use one depending of the second one for each object.
Thanks!

@rkewlani
Copy link

nice. works very well.

@wshbair
Copy link

wshbair commented Mar 11, 2019

Great it works very well with adding --silent option in curl

@flinox
Copy link

flinox commented Apr 3, 2019

it works! tkz, great job!

@hilmarf
Copy link

hilmarf commented Sep 2, 2019

{ "array": [ "foo", "bar" ], "other": "entry", "page": 1 }

what do I need to do, to get 'foo' and 'bar' ?
currently jsonValue array returns only foo

@wsieburgh
Copy link

I would advise to use jq, like this : cat file.json | jq .array would give:
[
"foo",
"bar"
]

@Akianonymus
Copy link

Small modification to display only one result for our $KEY.

awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -e 's/^[[:space:]]*//'

But... How to display whole result if it contains "," or ":" character?

jsonValue()
{
    num=$2
    grep \""$1"\" | sed  "s/\:/\n/"  | grep -v \""$1"\"  | sed "s/\"\,//g"  | sed 's/["]*$//' | sed 's/[,]*$//'| sed 's/^[ \t]*//'  | sed s/\"// | sed -n "${num}"p
}

Functionally same as @itstayyab, but , and : are also handled

Yes, i know, pretty late to the party.

@impressto
Copy link

Small modification to display only one result for our $KEY.
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -e 's/^[[:space:]]*//'
But... How to display whole result if it contains "," or ":" character?

jsonValue()
{
    num=$2
    grep \""$1"\" | sed  "s/\:/\n/"  | grep -v \""$1"\"  | sed "s/\"\,//g"  | sed 's/["]*$//' | sed 's/[,]*$//'| sed 's/^[ \t]*//'  | sed s/\"// | sed -n "${num}"p
}

Functionally same as @itstayyab, but , and : are also handled

Yes, i know, pretty late to the party.

Works perfectly. Thanks

@Akianonymus
Copy link

Akianonymus commented May 22, 2020

Small modification to display only one result for our $KEY.
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -e 's/^[[:space:]]*//'
But... How to display whole result if it contains "," or ":" character?

jsonValue()
{
    num=$2
    grep \""$1"\" | sed  "s/\:/\n/"  | grep -v \""$1"\"  | sed "s/\"\,//g"  | sed 's/["]*$//' | sed 's/[,]*$//'| sed 's/^[ \t]*//'  | sed s/\"// | sed -n "${num}"p
}

Functionally same as @itstayyab, but , and : are also handled
Yes, i know, pretty late to the party.

Works perfectly. Thanks

Just got the notification, glad it helped you. I have made some improvements since the last time.

###################################################
# Method to extract specified field data from json
# Globals: None
# Arguments: 2
#   ${1} - value of field to fetch from json
#   ${2} - Optional, nth number of value from extracted values, by default shows all.
# Input: file | here string | pipe
#   _json_value "Arguments" < file
#   _json_value "Arguments <<< "${varibale}"
#   echo something | _json_value "Arguments"
# Result: print extracted value
###################################################
_json_value() {
    declare LC_ALL=C num="${2:-}"
    grep -o "\"""${1}""\"\:.*" | sed -e "s/.*\"""${1}""\": //" -e 's/[",]*$//' -e 's/["]*$//' -e 's/[,]*$//' -e "s/\"//" -n -e "${num}"p
}

To avoid forking of multiple sed processes

@itstayyab
Copy link

Got my, mentioned after 6 years :) Glad that I contributed to something.

@grndvl1
Copy link

grndvl1 commented Sep 22, 2020

Awesome bit of code. Thank you saved me a ton of time and frustrations. Why there is no string compare like a contains just baffles me. The heavy handed use of grep is so silly. All I wanted was a simple if (something.contains(this)); then this allows me to achieve this by parsing the JSON response and then very easily create the if statement. Thank you! You are a time saver!

@thdoan
Copy link

thdoan commented Apr 1, 2021

Given this JSON in data.json:

{
  "id": "001",
  "color": "blue"
}

And I want to extract value "blue" from JSON property color in Windows git bash (no jq dependency), here's how I do it in a pinch:

grep color data.json | cut -d'"' -f4

Another way to do it:
https://raymii.org/s/snippets/Get_json_value_with_sed.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment