diff --git a/doc/usage.md b/doc/usage.md index c134a904..a89b8964 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -318,6 +318,7 @@ unary uses input and if more than one argument all as arguments ignoring the inp - `vgrep/1`, `vgrep/2` recursively match value - `bgrep/1`, `bgrep/2` recursively match buffer - `fgrep/1`, `fgrep/2` recursively match field name + - `grep_by/1` recursively match using a filter. Ex: `grep_by(. > 180 and . < 200)`, `first(grep_by(format == "id3v2"))`. - Buffers: - `tobits/0` - Transform input into a bits buffer not preserving source range, will start at zero. - `tobitsrange/0` - Transform input into a bits buffer preserving source range if possible. diff --git a/pkg/interp/grep.jq b/pkg/interp/grep.jq index 182dbfc5..58da6722 100644 --- a/pkg/interp/grep.jq +++ b/pkg/interp/grep.jq @@ -1,13 +1,7 @@ -def _grep($v; filter_cond; string_cond; other_cond): - if $v | type == "string" then - ( .. - | select(filter_cond and string_cond) - ) - else - ( .. - | select(filter_cond and other_cond) - ) - end; +def grep_by(f): + ( .. + | select(f)? + ); def _value_grep_string_cond($v; $flags): if type == "string" then test($v; $flags) @@ -18,46 +12,31 @@ def _value_grep_other_cond($v; $flags): . == $v; def vgrep($v; $flags): - _grep( - $v; - _is_scalar; - _value_grep_string_cond($v; $flags); - _value_grep_other_cond($v; $flags) - ); - + if $v | type == "string" then + grep_by(_is_scalar and _value_grep_string_cond($v; $flags)) + else + grep_by(_is_scalar and _value_grep_other_cond($v; $flags)) + end; def vgrep($v): vgrep($v; ""); def _buf_grep_any_cond($v; $flags): (isempty(tobytesrange | match($v; $flags)) | not)? // false; def bgrep($v; $flags): - _grep( - $v; - _is_scalar; - _buf_grep_any_cond($v; $flags); - _buf_grep_any_cond($v; $flags) - ); - + if $v | type == "string" then + grep_by(_is_scalar and _buf_grep_any_cond($v; $flags)) + else + grep_by(_is_scalar and _buf_grep_any_cond($v; $flags)) + end; def bgrep($v): bgrep($v; ""); def grep($v; $flags): - _grep( - $v; - _is_scalar; - _buf_grep_any_cond($v; $flags) or _value_grep_string_cond($v; $flags); - _buf_grep_any_cond($v; $flags) or _value_grep_other_cond($v; $flags) - ); - + if $v | type == "string" then + grep_by(_is_scalar and _buf_grep_any_cond($v; $flags) or _value_grep_string_cond($v; $flags)) + else + grep_by(_is_scalar and _buf_grep_any_cond($v; $flags) or _value_grep_other_cond($v; $flags)) + end; def grep($v): grep($v; ""); -def _field_grep_string_cond($v; $flags): - (._name | test($v; $flags))? // false; - def fgrep($v; $flags): - _grep( - $v; - _is_decode_value; - _field_grep_string_cond($v; $flags); - empty - ); - + grep_by(_is_decode_value and (._name | test($v; $flags))? // false); def fgrep($v): fgrep($v; ""); diff --git a/pkg/interp/testdata/grep.fqtest b/pkg/interp/testdata/grep.fqtest index 6921137b..712c6d3d 100644 --- a/pkg/interp/testdata/grep.fqtest +++ b/pkg/interp/testdata/grep.fqtest @@ -56,4 +56,22 @@ mp3> bgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x4 mp3> "64ff65ff66" | hex | bgrep("\u00ff"; "b") |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| 0x0|64 ff 65 ff 66| |d.e.f| |.: raw bits 0x0-0x4.7 (5) +mp3> grep_by(. == 44100) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| +0x20| 40| @|.frames[0].header.sample_rate: 44100 (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| +0xe0| 50 | P |.frames[1].header.sample_rate: 44100 (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| +0x1b0| 52 | R |.frames[2].header.sample_rate: 44100 (0) +mp3> grep_by(format == "id3v2") + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0]{}: (id3v2) +0x00|49 44 33 |ID3 | magic: "ID3" (valid) +0x00| 04 | . | version: 4 +0x00| 00 | . | revision: 0 +0x00| 00 | . | flags{}: +0x00| 00 00 00 23 | ...# | size: 35 +0x00| 54 53 53 45 00 00| TSSE..| frames[0:1]: +0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1| +0x20|30 30 00 |00. | +0x20| 00 00 00 00 00 00 00 00 00 00 | .......... | padding: raw bits (all zero) mp3> ^D