Print raw values with jq -r

echo '{"foo": "bar \" baz"}' | jq -r .foo

October 3, 2023bashoneliners

Explanation

By default, jq prints values as valid JSON, which means that string values are enclosed in double-quotes, for example:

$ echo '{"foo": "bar"}' | jq .foo
"bar"

When you don't want the enclosing double-quotes, some common but incorrect solutions use awk or tr:

... | jq .foo | awk -F'"' '{print $2}'
... | jq .foo | tr -d '"'

These work reasonably well for simple inputs:

  • The awk approach removes the double-quotes by setting " as the field separator and printing the 2nd field. So in the simple example with "bar", the 2nd field is bar, so it successfully produces the output without the double-quotes.
  • The tr solution simply deletes all double-quotes in the input, which works just as well in the simple case.

These approaches don't work well when the value contains embedded double-quotes. The correct solution is to use jq's -r or --raw-output flags, which tells jq to print "raw" values (without enclosing double-quotes), rather than as JSON strings.

$ echo '{"foo": "bar \" baz"}' | jq .foo | tr -d '"'
bar \ baz

$ echo '{"foo": "bar \" baz"}' | jq .foo | awk -F'"' '{print $2}'
bar \

$ echo '{"foo": "bar \" baz"}' | jq -r .foo
bar " baz