Samuel Mutel
Samuel Mutel

Reputation: 99

jq double backslash sometime removed

I have a first json file like this:

{
  "env_vars": {
    "TERRAFORM_CFG_TLS_CERT": "-----BEGIN CERTIFICATE----\\nMIIIqzCCB5O"
  }
}

If I use the command:

echo <file> | jq -r '.env_vars'

The result is as expected (the backslash are still there):

{
  "TERRAFORM_CFG_TLS_CERT": "-----BEGIN CERTIFICATE----\\nMIIIqzCCB5O"
}

But if i execute this command:

cat <file> | jq -r '.env_vars' | jq -r 'keys[] as $k | "\($k)=\"\(.[$k])\""'

The result is:

TERRAFORM_CFG_TLS_CERT: "-----BEGIN CERTIFICATE----\nMIIIqzCCB5O"

=> One backslash has been removed... why ? How to avoid this ?

Thanks.

Upvotes: 1

Views: 3485

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134861

You should output the string as json to preserve the escapes. By taking a string and outputting it raw, you're getting exactly what that string was, a literal backslash followed by an n.

$ ... | jq -r '.env_vars | to_entries[] | "\(.key): \(.value | tojson)"'

If any of the values are non-strings, add a tostring to the filter.

Upvotes: 0

peak
peak

Reputation: 116750

Using the -r option tells jq to "translate" the JSON string into a "raw" string by interpreting the characters that are special to JSON (see e.g. http://json.org). Thus, following the [mcve] guidelines a bit more closely, we could start with:

$ jq . <<< '"X\\nY"'
"X\\nY"

$ jq -r . <<< '"X\\nY"'
X\nY

If you check the json.org specification of strings, you'll see this is exactly correct.

So if for some reason you want each occurrence of \\ in the JSON string to be replaced by two backslash characters (i.e. JSON: "\\\\"), you could use sub or gsub. That's a bit tricky, because the first argument of these functions is a regex. Behold:

$ jq -r 'gsub("\\\\"; "\\\\")' <<< '"X\\nY"'
X\\nY

Upvotes: 3

Related Questions