curious-me
curious-me

Reputation: 71

Terminating jq processing when condition is met

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

Answers (3)

smac89
smac89

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

jq170727
jq170727

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

peak
peak

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

Related Questions