jq
jq copied to clipboard
JQ will not access keys beginning with @ (eg. as xml attributes generated by xq start)
I'm fairly sure this worked in a previous version, but since I had to upgrade my machine and reinstall JQ from scratch I am finding that I can't read the values of fields that begin with the @
character (as generated by XQ for XML attributes).
echo '{"@text":"foo", "@font":"bar", "@icon":"baz"}' | jq ."@text"
jq: error: syntax error, unexpected $end, expecting QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
.@text
jq: error: try .["field"] instead of .field for unusually named fields at <top-level>, line 1:
.@text
jq: 2 compile errors
Following the advice:
echo '{"@text":"foo", "@font":"bar", "@icon":"baz"}'| jq .["@text"]
no matches found: .[@text]
Ideally the result should be:
"foo"
What is the correct way to escape the @
so that JQ can access the desired values ?
This is not a jq issue. if you write ."@text"
in a file (e.g. file.jq
) and then run jq -f file.jq
, it will work.
The problem is that your shell quoting is completely messed up.
Your shell is a programming language and has its own syntax like any other programming language.
jq ."@text"
is exactly the same as jq .@text
; and, as you know, .@text
is not valid jq
code.
In jq .["@text"]
, .["@text"]
is a shell glob that expands to the name of the files that the current directory that matches that glob pattern. .["@text"]
will match files that are named ".t" ".e" ".@" or ".x". Other examples of a shell glob patterns are *.png
that matches all the files that end in ".png", and *.[ch]
that matches all the files that end in either ".c" or ".h".
Here is an example:
bash-5.1$ mkdir somedir; cd ./somedir; pwd
/home/emanuele6/somedir
bash-5.1$ touch .t file1.txt
bash-5.1$ ls -a
. .. file1.txt .t
bash-5.1$ echo .["@text"] # .["@text"] will expand to .t, so echo .t will be run
.t
bash-5.1$ echo '{"@text":"foo", "@font":"bar", "@icon":"baz"}'| jq .["@text"] # same as: jq .t
null
bash-5.1$ echo '{"t":10}" | jq .["@text"] # same as jq .t
10
bash-5.1$ touch file2.txt .x
bash-5.1$ ls -a
. .. file1.txt file2.txt .t .x
bash-5.1$ echo .["@text"]
.t .x
bash-5.1$ touch .e .a
bash-5.1$ ls -a
. .. .a .e file1.txt file2.txt .t .x
bash-5.1$ echo .["@text"]
.e .t .x
Use proper quoting:
jq '."@text"'