I'm trying to understand the behavior of jq pipes when using parentheses and commas. Let's consider this JSON example:
{"menu": [ {"id": "file","value": "File","menuitem": [ {"value": "New","onclick": "CreateNewDoc()" }, {"value": "Close","onclick": "CloseDoc()" } ] }, {"id": "photo","value": "Photo","menuitem": [ {"value": "New","onclick": "CreateNewDoc()" }, {"value": "Open","onclick": "OpenDoc()" } ] } ]}
First, let's apply a simple filter:
jq '.menu[].menuitem[] | .value'
Output:
"New""Close""New""Open"
This output is as expected.
Now, let's add a compound filter separated by a comma and group the first filter using parentheses:
jq '(.menu[].menuitem[] | .value), . | {}'
Output:
{}{}{}{}{}
It looks like second pipe is working with output of first filters
Question: why?
According to the jq documentation:
If two filters are separated by a comma, then the same input will be fed into both and the two filters' output value streams will be concatenated in order: first, all of the outputs produced by the left expression, and then all of the outputs produced by the right.
Following this logic, I would expect the output to be:
"New" // output of first filter"Close""New""Open"{} // output of second filter
However, this is not the case.
Corrected Filter
The filter works as expected if we add parentheses to the second filter:
jq '(.menu[].menuitem[] | .value), (. | {})'
Output:
"New""Close""New""Open"{}
Main question
Why does the pipe (|
) operator seemingly ignore the parentheses and comma in the first compound filter? What is the logic behind this behavior?