Reputation: 71
I am using jq to search for specific results in a large file. I do not care for duplicate entries matching this specific condition, and it takes a while to process the whole file. What I would like to do is print some details about the first match and then terminate the jq command on the file to save time.
I.e.
jq '. | if ... then "print something; exit jq" else ... end'
I looked into http://stedolan.github.io/jq/manual/?#Breakingoutofcontrolstructures but this didn't quite seem to apply
EDIT: The file I am parsing contains multiple json objects, one after another. They are not in an array.
Upvotes: 6
Views: 2142
Reputation: 43206
You can accomplish it using halt
and the inputs
builtin:
jq -n 'inputs | if ... then "something", halt else ... end'
Will print "something"
and terminate gracefully when the condition matches.
For this to work (i.e. terminate when condition is true), jq
needs the -n
parameter. See this issue
Upvotes: 2
Reputation: 14715
Here is an approach which uses a recent version of first/1
(currently in master)
def first(g): label $out | g | ., break $out;
first(inputs | if .=="100" then . else empty end)
Example:
$ seq 1000000000 | jq -M -Rn -f filter.jq
Output (followed by immediate termination)
"100"
Here I use seq
in lieu of a large JSON dataset.
Upvotes: 4
Reputation: 116957
To do what is requested is possible using features that were added after the release of jq 1.4. The following uses foreach and inputs:
label $top
| foreach inputs as $line
# state: true means found; false means not yet found
(false;
if . then break $top
else if $line | tostring | test("goodbye") then true else false end
end;
if . then $line else empty end
)
Example:
$ cat << EOF | jq -n -f exit.jq
1
"goodbye"
3
4
EOF
Result: "goodbye"
Upvotes: 3