Skip to content

Commit

Permalink
interp: Add --value-output/-V option to do tovalue before output
Browse files Browse the repository at this point in the history
Idea is to skip display so that JSON is outputted instead of showing tree and hexdump etc.
  • Loading branch information
wader committed Apr 13, 2023
1 parent 5c69fcc commit 427ce78
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 7 deletions.
19 changes: 17 additions & 2 deletions doc/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,21 @@ fq 'd({verbose: true})' file

# JSON representation for whole file
fq tovalue file
# or use -V (--value-output) that does tovalue automatically
fq -V . file
# or -Vr if the value is a string and you want a "raw" string
fq -Vr .path.to.string file
# JSON but raw bit fields truncated
fq -o bits_format=truncate tovalue file
# JSON but raw bit fields as md5 hex string
fq -o bits_format=md5 tovalue file
# look up a path
fq '.some[1].path' file
# look up a path and output JSON
fq -V '.some[1].path' file
# can be a query that outputs multiple values
# this outputs first and last value in .same array and .path, three values in total
fq -V '.some[0,-1], .path' file

# grep whole tree by value
fq 'grep("^prefix")' file
Expand Down Expand Up @@ -73,7 +84,7 @@ fq -o force=true -d mp4 file.mp4

### CLI arguments

Most of fq's CLI argument are borrowed from jq and works in the same way.
Most of jq's CLI arguments work with fq. But here are some additional ones specific to fq:

#### Decode format `--decode`, `-d NAME`

Expand All @@ -85,7 +96,7 @@ Force format to decode instead of probing.

Start interactive REPL.

Can be used with both no, one and multiple inputs, ex just `fq -i ` start a REPL with `null` input, `fq -i 123` with the number 123 as input, `fq -i . a b` with two files as input. Also works with `--slurp`.
Can be used with no input, one and multiple inputs, for example just `fq -i ` starts a REPL with `null` input, `fq -i 123` with the number 123 as input, `fq -i . a b` with two files as input. This also works with `--slurp`. In the REPL it is also possible to start a sub-REPLs by ending a query with `<query> | repl`, use ctrl-D to exit the sub-REPL. The sub-REPL will evaluate separately on each output from the query it was started. Use `[<query>] | repl` if you want to "slurp" into an array.

#### Set option `--options`,`-o KEY=VALUE|@PATH`

Expand All @@ -97,6 +108,10 @@ Can be used with both no, one and multiple inputs, ex just `fq -i ` start a REPL

Specify a global option or a format option, ex: `-o decode_samples=false` would for some container decoders like `mp4` and `matroska` disable decoding of samples.

#### Value output `--value-output`, `-V`

Output JSON value instead of decode tree. Use `-Vr` if you want raw string (no quotes).

### Display output

`display` or `d` is the main function for displaying values and is also the function that will be used if no other output function is explicitly used. If its input is a decode value it will output a dump and tree structure or otherwise it will output as JSON.
Expand Down
2 changes: 1 addition & 1 deletion pkg/interp/help.jq
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ def _help($arg0; $topic):
( "Example usages:"
, " fq . file"
, " fq d file"
, " fq -V '.path[1].value' file"
, " fq tovalue file"
, " fq -r to_toml file.yml"
, " fq -s -d html 'map(.html.head.title?)' *.html"
, " cat file.cbor | fq -d cbor torepr"
, " fq 'grep(\"^main$\") | parent' /bin/ls"
, " fq -r 'grep_by(.protocol==\"icmp\").source_ip | tovalue' *.pcap"
, " fq -i"
)
elif . == "banner" then
Expand Down
2 changes: 1 addition & 1 deletion pkg/interp/interp.jq
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def display($opts):
( . as $c
| options($opts) as $opts
| try _todisplay catch $c
| if _can_display then _display($opts)
| if ($opts.value_output | not) and _can_display then _display($opts)
else
( if _is_string and $opts.raw_string then print
else _print_color_json($opts)
Expand Down
17 changes: 15 additions & 2 deletions pkg/interp/options.jq
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def _opt_build_default_fixed:
slurp: false,
string_input: false,
unicode: ($stdout.is_terminal and env.CLIUNICODE != null),
value_output: false,
verbose: false,
}
);
Expand Down Expand Up @@ -106,6 +107,7 @@ def _opt_options:
slurp: "boolean",
string_input: "boolean",
unicode: "boolean",
value_output: "boolean",
verbose: "boolean",
width: "number",
};
Expand Down Expand Up @@ -219,6 +221,11 @@ def _opt_eval($rest):
else null
end
),
value_output: (
if .value_output == true then true
else null
end
),
}
| with_entries(select(.value != null))
);
Expand Down Expand Up @@ -474,8 +481,8 @@ def _opt_cli_opts:
},
"raw_string": {
short: "-r",
# for jq compat, is called raw string internally, "raw output" is if
# we can output raw bytes or not
# for jq compat, is called raw string internally, is different from "raw output" which
# is if we can output raw bytes or not
long: "--raw-output",
description: "Raw string output (without quotes)",
bool: true
Expand All @@ -498,6 +505,12 @@ def _opt_cli_opts:
description: "Force unicode output",
bool: true
},
"value_output": {
short: "-V",
long: "--value-output",
description: "Output JSON value (-Vr for raw string)",
bool: true
},
"show_version": {
short: "-v",
long: "--version",
Expand Down
4 changes: 3 additions & 1 deletion pkg/interp/testdata/args.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Usage: fq [OPTIONS] [--] [EXPR] [FILE...]
Example usages:
fq . file
fq d file
fq -V '.path[1].value' file
fq tovalue file
fq -r to_toml file.yml
fq -s -d html 'map(.html.head.title?)' *.html
cat file.cbor | fq -d cbor torepr
fq 'grep("^main$") | parent' /bin/ls
fq -r 'grep_by(.protocol=="icmp").source_ip | tovalue' *.pcap
fq -i

--arg NAME VALUE Set variable $NAME to string VALUE
Expand All @@ -44,6 +44,7 @@ Example usages:
--repl,-i Interactive REPL
--slurp,-s Slurp all inputs into an array or string (-Rs)
--unicode-output,-U Force unicode output
--value-output,-V Output JSON value (-Vr for raw string)
--version,-v Show version
$ fq -i
null> ^D
Expand Down Expand Up @@ -101,6 +102,7 @@ sizebase 10
slurp false
string_input false
unicode false
value_output false
verbose false
width 135
$ fq -X
Expand Down
1 change: 1 addition & 0 deletions pkg/interp/testdata/options.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ $ fq -n options
"slurp": false,
"string_input": false,
"unicode": false,
"value_output": false,
"verbose": false,
"width": 135
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/interp/testdata/value_output.fqtest
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
$ fq -V '.headers[0].header[]' test.mp3
"ID3"
4
0
{
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
}
35
$ fq -Vr '.headers[0].header[]' test.mp3
ID3
4
0
{
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
}
35

0 comments on commit 427ce78

Please sign in to comment.