Parse JSON using Python?
If you would use:
$ cat members.json | \
python -c 'import json,sys;obj=json.load(sys.stdin);print obj;'
you can inspect the structure of the nested dictonary obj
and see that your original line should read:
$ cat members.json | \
python -c 'import json,sys;obj=json.load(sys.stdin);print obj["hits"]["hits"][0]["_source"]["'$1'"]';
to the to that "memberId" element. This way you can keep the Python as a oneliner.
If there are multiple elements in the nested "hits" element, then you can do something like:
$ cat members.json | \
python -c '
import json, sys
obj=json.load(sys.stdin)
for y in [x["_source"]["'$1'"] for x in obj["hits"]["hits"]]:
print y
'
Chris Down's solution is better for finding a single value to (unique) keys at any level.
With my second example that prints out multiple values, you are hitting the limits of what you should try with a one liner, at that point I see little reason why to do half of the processing in bash, and would move to a complete Python solution.
Another way to do this in bash is using jshon. Here is a solution to your problem using jshon
:
$ jshon -e hits -e hits -a -e _source -e memberId -u < foo.json
0x7b93910446f91928e23e1043dfdf5bcf
0x7b93910446f91928e23e1043dfdf5bcG
The -e
options extract values from the json. The -a
iterates over the array and the -u
decodes the final string.
Well, your key is quite clearly not at the root of the object. Try something like this:
json_key() {
python -c '
import json
import sys
data = json.load(sys.stdin)
for key in sys.argv[1:]:
try:
data = data[key]
except TypeError: # This is a list index
data = data[int(key)]
print(data)' "$@"
}
This has the benefit of not just simply injecting syntax into Python, which could cause breakage (or worse, arbitrary code execution).
You can then call it like this:
json_key hits hits 0 _source memberId < members.json