In Mac Terminal, I'm trying to parse the "name" out of this JSON response:

{"created_at":"2012-08-27T20:04:27Z","deleted_at":null,"id":21462840,"item_type":"video","name":"CastingBy-v12 mixed.mov","private":true,"redirect_url":null,"remote_url":"http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov","source":"Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)","updated_at":"2012-08-27T20:13:38Z","view_counter":2,"href":"http://my.cl.ly/items/2840","icon":"http://my.cld.me/images/item-types/video.png","subscribed":true,"url":"http://files.housenyc.com/1I3E2F3C","content_url":"http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov","download_url":"http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov","gauge_id":null}

I'm using

sed 's/{.*?"name":"\(.+?\)".*/\1/'

but it returns the whole string.

I want it to return just

CastingBy-v12 mixed.mov

  • 1
    Can you use Python, instead?
    – Keith
    Aug 27 '12 at 22:09

Parsing json with just sed is as problematic as parsing HTML - in short: since elements can embed other elements and regex doesn't support recursion, it's essentially impossible to parse correctly with just regexp.

There's a PCRE solution to parsing and validating json here: https://stackoverflow.com/questions/2583472/regex-to-validate-json - I haven't used or tested it so I'll have to take the author's word that it works...but PCRE does a lot of things that just aren't in the basic or extended regexps supported by sed.

In any case, IMO you're better off using perl or python or awk and one of the json parsing libs for those languages, or a specialised json parsing tool - several are mentioned here:


Any of them can be used to extract data from JSON input for use in a shell script. Or you could write your entire program within that language.

For example, piping your json data into python -mjson.tool results in this:

$ echo "JSONDATAHERE" | python -m json.tool
    "content_url": "http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov", 
    "created_at": "2012-08-27T20:04:27Z", 
    "deleted_at": null, 
    "download_url": "http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov", 
    "gauge_id": null, 
    "href": "http://my.cl.ly/items/2840", 
    "icon": "http://my.cld.me/images/item-types/video.png", 
    "id": 21462840, 
    "item_type": "video", 
    "name": "CastingBy-v12 mixed.mov", 
    "private": true, 
    "redirect_url": null, 
    "remote_url": "http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov", 
    "source": "Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)", 
    "subscribed": true, 
    "updated_at": "2012-08-27T20:13:38Z", 
    "url": "http://files.housenyc.com/1I3E2F3C", 
    "view_counter": 2

which you can then pipe into sed like this:

$ echo "JSONDATAHERE" | python -m json.tool | sed -n -e '/"name":/ s/^.*"\(.*\)".*/\1/p'
CastingBy-v12 mixed.mov

Relying on the greedy nature of regexp, the sed script extracts everything between the second-last " and the last " character on any line containing "name":.

  • BTW, yes I have used regexps to parse HTML and JSON. I've even made it work for my specific needs at the time...but I know that what I did was fragile and prone to failure and highly sensitive to the input data. These days I usually find it easier and far more reliable to pre-process the json data with python -m json.tool and then pipe that into sed or awk. or just write a perl script using the JSON module. I'll still use regexps for a quick and dirty one-liner hack, but for anything intended to be used repeatedly, I'll do it properly.
    – cas
    Aug 27 '12 at 22:21

This is the expression you are looking for:

sed -e 's/^.*"name":"\([^"]*\)".*$/\1/' infile

It results to:

CastingBy-v12 mixed.mov

In yours there are several errors:

  • In sed only greeding expression can be used: .*? and .+? are incorrect.
  • The + must be escaped.
  • Use [^"]* to avoid that the regular expression matches until last double quotes of the string.
  • Thanks for all the tips! But that still returns the entire string. I'm using echo "{my big string}" | sed 's/^.*"name":"\([^"]\+\)".*$/\1/'
    – Dan
    Aug 27 '12 at 21:53
  • @Ze'ev: Sorry. It works for me and I cannot catch the issue that doesn't work for you.
    – Birei
    Aug 27 '12 at 22:03
  • Maybe because I'm on Mac using Terminal?
    – Dan
    Aug 27 '12 at 22:14
  • 1
    @zeev, Yes, Mac uses a BSD sed that doesn't have all the gnu features. I tested a bit and it seems Mac's sed doesn't recognize either + or \+. Change that to * .
    – Kevin
    Aug 27 '12 at 23:24
  • @Kevin AHA! That did it! Thanks! | sed 's/^.*"name":"\([^"]*\)".*$/\1/'
    – Dan
    Aug 28 '12 at 3:29

This dosn't answer your question directly. But if you need to do such things on a regular basis, consider using a generally available programming language like Perl, Python, Ruby.

In Ruby, your solution would be:

some_command_that_emits_json | ruby -e "require 'rubygems';require 'json'; output=JSON.parse(STDIN.gets); puts output['name']"


Going from this thread, this does the trick:

echo {json...foo} | awk -F=":" -v RS="," '$1~/"name"/ {print}' | sed 's/\"//g' | sed 's/name://'

  • You probably want RS="," to become RS=",|{|}"; in case what you are looking for is at the beginning or end of the line.
    – A T
    Feb 3 '14 at 4:24

Here's one way to do it with the JSON module of perl:

 json_producing_process | perl -MJSON -lne 'print from_json($_)->{name}'

Assuming you have jq available on your macOS system (e.g. by installing it via the Homebrew package manager):

some_command | jq -r '.name'

... where some_command is a command producing your JSON document. The jq command here extracts the value of the name key and decodes it (if needed).

Given your document in the question, this would produce a single line saying

CastingBy-v12 mixed.mov

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.