3

I'm getting a "parse error" when I split a text line on multiple lines and show the JSON file on screen with the command jq . words.json.

The JSON file with the text value on a single line looks like this

{
    "words" : "one two three four five"
}

The command jq . words.json works fine and shows the JSON file on screen.

But when I split the value "one two three four five" on two lines and run the same command I get a parse error

{
    "words" : "one two   
    three four five"
                   ^
}  
                 

parse error: Invalid string: control characters from U+0000 through U+001F must be escaped at line 3, column 20

The parse error points to the " character at the end of the third line.

How can I solve this?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Anthony
  • 33
  • 1
  • 1
  • 4

6 Answers6

4

That's because the JSON format is invalid. It should look like this:

{
    "words" : "one two \nthree four five"
}
CodiMech25
  • 443
  • 3
  • 9
4

That's not valid JSON; JSON strings don't contain literal newlines. But you can do:

jq -Rnr '[inputs] | join("\\n") | fromjson | .choices[0].message.content' sample.json
oguz ismail
  • 1
  • 16
  • 47
  • 69
2

The parse error points to the " at the end of the third line.

The way jq flags this error may be counterintuitive, but the error in the JSON precedes the indicated quote-mark.

If the error is non-obvious, it may be that an end-quote is missing on the prior key or value. In this case, the value that matches the criteria U+0000 through U+001F could be U+000A, which is the line feed character in ASCII.

In the case of this question, the line feed was inserted intentionally. But, unescaped, this is invalid JSON.

Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173
1

You have to escape end of line in JSON:

{
  "words" : "one two\nthree four five"
}
Michał Grzejszczak
  • 2,599
  • 1
  • 23
  • 28
  • 1
    Minor semantic nit: this is a string that includes an escape sequence that *represents* a newline character, rather than escaping a literal newline character. – chepner Aug 02 '18 at 16:14
1

To convert the text with the multi-line string to valid JSON, you could use any-json (https://www.npmjs.com/package/any-json), and pipe that into jq:

$ any-json --input-format=cson split-string.txt
{
    "words": "one two three four five"
}
$ any-json --input-format=cson split-string.txt | jq length
1

For more on handling almost-JSON texts, see the jq FAQ: https://github.com/stedolan/jq/wiki/FAQ#processing-not-quite-valid-json

peak
  • 105,803
  • 17
  • 152
  • 177
1

this is another option for user @randombits

cat sample.json | jq -R '.' | jq -s '.' | jq -r 'join("")' | jq -r '.choices[0].message.content'