Output formats
Every output format, how to narrow columns, and how to template rows.
Every list command renders through the same formatter. Pick a format with -o,
or let bili choose: a table when writing to a terminal, JSONL when piped.
Formats
bili search lofi -o table # aligned columns for reading
bili search lofi -o list # one short named section per record
bili search lofi -o markdown # a pipe table that pastes into an issue
bili search lofi -o jsonl # one JSON object per line, for piping
bili search lofi -o json # a single JSON array
bili search lofi -o csv # spreadsheet friendly
bili search lofi -o tsv # tab-separated
bili search lofi -o url # just the URL column
bili search lofi -o raw # the underlying record as pretty-printed JSON
| Format | Best for |
|---|---|
table |
Reading on a terminal |
list |
Reading one record top to bottom, and it streams as records arrive |
markdown |
Pasting into an issue or a README |
jsonl |
Piping into another tool, one object at a time |
json |
Loading a whole result as an array |
csv / tsv |
Spreadsheets and quick column math |
url |
Feeding URLs into other commands |
raw |
The full record, pretty-printed |
There is no yaml. It was an undocumented alias and was removed in v0.1.1; pipe
-o jsonl through yq if that is what you want.
Rich, lossless records
bili keeps the fields the API returns rather than flattening them. The table,
list, markdown, csv and url views are readable projections; json,
jsonl and raw are the complete record. When in doubt about what a command
knows, ask for JSON:
bili video BV17x411w7KC -o json | jq 'keys'
Narrowing columns
Keep only the fields you want, in the order you list them:
bili search lofi --fields bvid,title,view_count
--no-header drops the header row in table and csv output, which is handy
when a downstream tool expects bare rows.
Templating rows
For full control over each line, apply a Go text/template. The template runs
against the record as JSON, so the names are the JSON keys exactly as they
appear in -o json, lower case and underscored, not the Go field names:
bili search lofi --template '{{.bvid}} {{.title}}'
bili video BV17x411w7KC --template '{{.title}} has {{.view_count}} views'
A name that is not a key renders as <no value> rather than failing, so check a
template against -o json | jq keys when a line comes out empty.
The envelope
Every record carries an envelope describing the reading rather than the thing
read: which endpoint answered, whether the request was signed, what state the
response was sorted into, when, and the size of the body it came out of.
bili user 946974 -o jsonl | jq .envelope
It is hidden from table and csv by default, because provenance is worth
having on every record and worth a column on none of them. Ask for it by name
when you want it:
bili user 946974 -o table --fields name,envelope
Fields that are not there
envelope.missed names the fields the record does not carry and says why for
each. This matters most on bili user, which is four requests behind one row:
the identity comes from one endpoint and the counts come from three others, and
any of them can refuse while the rest answer.
A refused count is left out of the record rather than printed as zero. In JSON the key is simply absent; in a table or a csv the cell is empty. A count that really is zero is still a zero, which is the whole point of the distinction.
$ bili user 946974 -o csv --fields name,follower_count,total_view
name,follower_count,total_view
影视飓风,17140391,
$ bili user 946974 -o jsonl | jq '.envelope.missed.total_view'
"x/space/upstat refused_silent: code 0 with no payload"
An absent field with no entry in missed was absent because there was nothing
to put in it. An absent field with an entry was stopped by something, and the
entry is what stopped it.
Why auto-detection helps
Because the default adapts to the destination, the same command reads well by hand and parses cleanly in a pipe:
bili search lofi # a table, because this is a terminal
bili search lofi | wc -l # JSONL, because this is a pipe
You only reach for -o when you want something other than that default.