19

I would like to use python to parse JSON in batch scripts, for example:

HOSTNAME=$(curl -s "$HOST" | python ?)

Where the JSON output from curl looks like:

'{"hostname":"test","domainname":"example.com"}'

How can I do this with a single line python command?

6
  • 3
    Much easier to use something like jq from the command line, which is dedicated to parsing JSON and so has a cleaner design: HOSTNAME=$(curl -s $HOST | jq -r '.hostname'). Commented Jul 20, 2016 at 17:39
  • 2
    Down voters, please state why you are down voting. It's difficult to improve questions if you don't know what's wrong with them. Commented Jul 20, 2016 at 17:41
  • 2
    @chepner true, but I don't have and can't install jq on the host in question, but I do have python and the json module. Commented Jul 20, 2016 at 17:43
  • 1
    For what purpose do you require the Python code to be "a single line"? Commented Jul 23, 2016 at 10:01
  • 3
    It's much easier to work with single line commands in a batch script. Multi line Python statements that require Python indentation are difficult to integrate into scripts using pipes and redirects without having to put the Python statements into a separate file as a Python script. Commented Jul 23, 2016 at 10:13

4 Answers 4

23

Based on the JSON below being returned from the curl command ...

'{"hostname":"test","domainname":"example.com"}'

You can then use python to extract the hostname using the python json module:

HOSTNAME=$(curl -s "$HOST" |
  python -c \
    'import json,sys;print(json.load(sys.stdin)["hostname"])')

Note that I have split the line using a \ to make it more readable on stackoverflow. I've also simplified the command based on chepner's comment.

Original source: Parsing JSON with Unix tools

See also: https://wiki.python.org/moin/Powerful%20Python%20One-Liners

Sign up to request clarification or add additional context in comments.

3 Comments

For a one-liner, I wouldn't bother with the intermediate variable obj: python -c 'import json,sys;print json.load(sys.stdin)["hostname"].
For python3: python3 -c 'import json,sys; print(json.load(sys.stdin)["hostname"])'. Same thing but with parens for print
This answer, while technically correct, is not conveniently formatted with executable code snippets. For instance most people are more interested in parsing the JSON, than in making a curl call to a service running on particular host. (I tried to edit it for clarity, but was rejected.)
18
echo '{"hostname":"test","domainname":"example.com"}' | python -m json.tool

2 Comments

This only prettily prints the incoming json. There is no extraction of variables or array members.
echo '{"hostname":"test","domainname":"example.com"}' | python -m json.tool | awk '/hostname/{ printf $2 }' | tr --delete '"'
6

Since Python is multiplatform, is important to note differences between Linux and Windows, especially because of how they treat double-quotes/single-quotes differently.

Second, some previous answers are a little bit obsolete: in python2, print without parentheses was permitted. Nevertheless, in python3, print must be between parentheses.

Linux (bash)

It doesn't matter how you put double/single quotes. Json can be parsed in both ways with "keys" or 'keys'

HOSTNAME=$(curl -s "$HOST" |
  python3 -c 'import json,sys;print(json.load(sys.stdin)["hostname"])')

It also works: (pay attention at single/double quote at key)

HOSTNAME=$(curl -s "$HOST" |
  python3 -c "import json,sys;print(json.load(sys.stdin)['hostname'])")

Windows (powershell)

Keys in json MUST be between single quotes. Only the following syntax is accepted.
The ConvertTo-Json function generates object and works with keys between single quotes.

$HOSTNAME=(Invoke-RestMethod $HOST | `
  ConvertTo-Json | `
  python3 -c "import json,sys; print(json.load(sys.stdin)['hostname'])")

1 Comment

This is a very nice answer to my question. Up voted.
3

Run this:

$ python -m json.tool

It reads input from stdin and print out in a nicely. So with your questions:

HOSTNAME=$(curl -s "$HOST" | python -m json.tool )

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.