stephan
stephan

Reputation: 45

Embedding jq in bash - what needs to be escaped?

I'm trying to inline a jq construct that itself requires pipes. I suspect I'm running into issues because bash is treating them as bash-level pipes, rather than part of the jq.

Testing at jqplay.org, this .[1] | [.timeEnded, .lifecycleState] | flatten gets me the result I need.

Trying to embed that in bash, I am trying to do something like:

status=$(curl -X GET <URL> | jq -r -c '.[1] | [.timeEnded, .lifecycleState] | flatten' | awk -F, '{print $2}' | sed 's/"//g')

With no escaping the pipes within the jq, I get

[.timeEnded,: command not found

I tried to escape those pipes as jq -r -c '.[1] \| [.timeEnded, .lifecycleState] \| flatten' but that gets me a jq syntax error:

jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
.[1] \| [.timeEnded, .lifecycleState] \| flatten
jq: 1 compile error

Wrapping the entire jq command in double quotes (as well as the escape chars) gave me the same syntax error. I'm sure there's probably an easy answer here, but jq is new to me.

Any help would be appreciated.

Upvotes: 1

Views: 1723

Answers (2)

peak
peak

Reputation: 116870

Embedding jq in bash - what needs to be escaped?

Using bash and bash-like shells, jq programs can often be specified quite simply on the command line using single-quoted strings, e.g.

$ jq -n '"abc"'
"abc"

However, using this technique, single quotes are a headache since bash does not allow single quotes within ordinary single-quoted strings. The workaround is quite horrible:

$ jq -n '"a'"'"'b"'
"a'b"

So if the jq program does have embedded single-quotes, then it's probably time to use the -f option, but if that is not an option, then using the form $'STRING' should be considered.

In this case, though, there are two characters that can occur in jq programs and that will require attention: single-quotes and backslashes

For example:

$ jq -n $'"a\\tb" | "\'\\(.)\'"'
"'a\tb'"

If I'm not mistaken, the required escaping can be done using:

sed -e $'s/\'/\\\'/g' -e $'s/\\\\/\\\\\\\\/g'

Upvotes: 0

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185530

I clearly suspect that you have an unbreakable space in this part:

jq -r -c '.[1] | [...

So, edit the line manually, and replace all spaces with real spaces (taking care to not type unbreakable spaces again with AltGr+space)

Upvotes: 1

Related Questions