Skip to content
Latchkey

jq @csv and @tsv : Emit Delimited Rows

jq @csv formats an array as one comma-separated row with proper quoting; @tsv does the same with tabs.

When a step needs a CSV report or a tab-separated list to feed another tool, @csv and @tsv produce correctly escaped rows from API data.

What it does

@csv takes an array of scalars and renders a CSV row, quoting strings and escaping embedded quotes. @tsv renders a tab-separated row, escaping tabs and newlines. Both require the input to be an array, so map fields into one first.

Common usage

Terminal
# header plus rows from an API array
jq -r '["name","stars"], (.[] | [.name, .stargazers_count]) | @csv' repos.json
# tab-separated for cut/awk
gh api repos/cli/cli/labels --jq '.[] | [.name, .color] | @tsv'

Formats

FormatWhat it does
@csvArray to a quoted CSV row
@tsvArray to a tab-separated row
-rRequired so quotes are not double-escaped
[ .a, .b ]Build the row array before formatting

In CI

Always pair @csv/@tsv with -r; without it jq prints the row as a JSON string with the quotes escaped, which no spreadsheet or cut command will parse. Emit a header row first with a literal array.

Common errors in CI

"jq: error: <stdin>:0: @csv: input must be an array" means you applied @csv to an object or scalar; wrap the fields in [ ... ] first. "jq: error (at <stdin>:0): object ({...}) is not valid in a csv row" means a column value is itself an object; flatten it to a scalar.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →