econ
econ

Reputation: 547

jq - raw output without evaluating new line character

The json files that I am processing contain newline characters \n in the value fields. For example: { "a": "b\n" }

I am trying to generate csv files that contain output, which includes such values. However, when I try jq -r '[.a]|@csv', I get:

"b
"

The \n character is evaluated. I believe this is how -r option is intended to work, so I tried the output without it,jq '[.a]|@csv', and I get:

"\"b\n\""

This is closer to what I want, but the output is quoted and csv-quotes are escaped. My desired output is:

"b\n"

This becomes troublesome on my actual files, because my csv output contains values with double quotes.

For example:

{
  "a": "She said: \"Yes!\"\n",
  "b": "We said: \"Hello!\"\n"
}

My desired output in this case is:

"She said: \"Yes!\"\n","We said: \"Hello!\"\n"

Upvotes: 2

Views: 3722

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134811

You'll have to escape the newline characters. They are valid JSON characters so it won't be treated differently.

[.a, .b] | map(sub("\n"; "\\n")) | @csv

This would give you

"She said: ""Yes!""\n","We said: ""Hello!""\n"

Note that the inner quotes are doubled, that's how you escape double quotes within a CSV line. It is not escaped using backslashes.

In case there are multiple \n symbols then using gsub instead of sub will do the trick.

Upvotes: 3

econ
econ

Reputation: 547

Based on the answer to a related question (Processing json array with jq and quoted values), I can do the following:

 while read -r a; read -r b; do echo "$a,$b"; done < <(jq -c '.'a,.b test.txt)

This gives:

"She said: \"Yes!\"\n","We said: \"Hello!\"\n"

This is not very general, though, since it must be adjusted to fit the number of fields.

Upvotes: 0

Related Questions