213

I'm trying to get jq to parse a JSON structure like:

{ "a" : 1, "b" : 2, "c" : "{\"id\":\"9ee ...\",\"parent\":\"abc...\"}\n" } 

That is, an element in the JSON is a string with escaped json.

So, I have something along the lines of $ jq [.c] myFile.json | jq [.id]

But that crashes with jq: error: Cannot index string with string

This is because the output of .c is a string, not more JSON. How do I get jq to parse this string?

My initial solution is to use sed to replace all the escape chars (\":\", \",\" and \") but that's messy, I assume there's a way built into jq to do this?

Thanks!

edit: Also, the jq version available here is:

$ jq --version jq version 1.3 

I guess I could update it if required.

1
  • 1
    This question also helps if you are looking for: "How to unescape json string using jq?" Commented Oct 18, 2017 at 14:37

4 Answers 4

371

jq has the fromjson builtin for this:

jq '.c | fromjson | .id' myFile.json 

fromjson was added in version 1.4.

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

5 Comments

Thank you. This works. I'll accept this answer, as it's more 'idiomaitic' I feel. Cheers.
@ColinGrogan please do.
@ColinGrogan: I don't see any reason to change the accepted answer since you clearly wrote in your question that you used the version 1.3 of jq in which the fromjson feature isn't available. In other words, even if this answer is interesting, it doesn't answer the question.
Is it possible to use this but on an entire json file (not specifying the .id property)?
@FlorianCastelain yes, either omit it or use dot: jq 'fromjson | .' myfile, where myfile contains "{\"key\":1, \"word\":\"cat\"}"
90

You can use the raw output (-r) that will unescape characters:

jq -r .c myfile.json | jq .id 

ADDENDUM: This has the advantage that it works in jq 1.3 and up; indeed, it should work in every version of jq that has the -r option.

2 Comments

-r is much easier than the accepted answer. You got my upvote. I use jq to view json from my clipboard. So when I run into this I do: pbpaste | jq -r
bonus: if you want to escape quotes you can use sed: pbpaste | sed -e 's/\\\"/\"/g'. this helps when you have escaped json that contains escaped json. Take out the first level of escaped quotes with sed and then jq can remove the last level. e.g pbpaste | sed -e 's/\\\"/\"/g' | jq -r
4

Motivation: you want to parse JSON string - you want to escape a JSON object that's wrapped with quotes and represented as a String buffer, and convert it to a valid JSON object. For example:

some JSON unescaped string :

"{\"name\":\"John Doe\",\"position\":\"developer\"}" 

the expected result ( a JSON object ):

{"name":"John Doe","position":"developer"} 

Solution: In order to escape a JSON string and convert it into a valid JSON object use the sed tool in command line and use regex expressions to remove/replace specific characters:

cat current_json.txt | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g' 

s/\\\"/\"/g replacing all backslashes and quotes ( \" ) into quotes only (")

s/^.//g replacing the first character in the stream to none character

s/.$//g replacing the last character in the stream to none character

3 Comments

I had a similar problem. Used the same sed command verbatum. Bravo! Pipe that result to jq -r and you can process escaped json inside your json.
Boo, hiss re: trying to parse JSON with sed. Any tool that tries to match just a few of the most common escapings is going to miss others (for example, you're handling " but not \t)
I had to also replace double quote characters: cat a.json | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g' -e 's/""/"/g' | jq
0

Since you are open to alternatives to JQ, I would like to also suggest a more intuitive way to achieve what you were doing with JQ.

Toolkit.app has a JSON query tool that lets you run plain JS functions to query and transform JSON. In your case, you can just input your JSON into the input field and add the following transform function to get your desired result.

Disclaimer: I created this tool because JQ syntax still feels unintuitive to me and I almost always have to open the manual, google the solution or ask an LLM.

https://gettoolkit.app/tools/data/json-query-transform

function transform(data) { return JSON.parse(data.c).id; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.