Skip to content

vgrid convert

Convert between file formats.

Terminal window
vgrid convert [input] -t <format> [options]
OptionDescription
--from, -fInput format (required when reading from stdin)
--to, -tOutput format: csv, tsv, json, lines (required)
--output, -oOutput file (default: stdout)
--sheetSheet index (0-based) or name (case-insensitive). .sheet and .xlsx only — errors on single-sheet formats (csv, tsv, json, lines). Default: sheet 0.
--delimiterCSV/TSV delimiter (default: , for csv, \t for tsv)
--headersFirst row is headers (affects JSON object keys)
--whereFilter rows by column value (requires --headers; repeatable)
--selectSelect columns to output (requires --headers; repeatable; comma-separated)
--renameRename columns (requires --headers). Comma-separated OLD:NEW pairs.
-q, --quietSuppress stderr notes (e.g. skipped-row counts)
Terminal window
# XLSX to JSON with headers as keys
vgrid convert data.xlsx -t json --headers
# CSV to JSON via stdin
cat data.csv | vgrid convert -f csv -t json
# JSON to CSV
curl -s api.example.com/data | vgrid convert -f json -t csv
# Select a specific sheet from XLSX (by name)
vgrid convert report.xlsx -t csv --sheet "Q4 Data"
# Select a specific sheet (by index)
vgrid convert report.xlsx -t csv --sheet 2
# Export a named sheet from a .sheet workbook
vgrid convert model.sheet -t json --sheet "Forecast" --headers
# File to file
vgrid convert data.xlsx -t csv -o data.csv

Filter rows before writing output. Requires --headers so column names can be resolved. Multiple --where flags combine as AND (all must match).

Terminal window
# Pending transactions
vgrid convert rh_transactions.csv -t csv --headers --where 'Status=Pending'
# Pending charges (negative amounts)
vgrid convert rh_transactions.csv -t csv --headers \
--where 'Status=Pending' --where 'Amount<0'
# Vendor name contains (case-insensitive)
vgrid convert rh_transactions.csv -t csv --headers \
--where 'Description~"google workspace"'
# Pipe filtered output into calc
vgrid convert data.csv -t csv --headers --where 'Status=Pending' | \
vgrid calc '=SUM(E:E)' -f csv --headers
SyntaxMeaning
col=valueEquals (typed — see below)
col!=valueNot equals (typed)
col<numberLess than (numeric)
col>numberGreater than (numeric)
col~substringContains (case-insensitive)

>= and <= are not supported. Use the negation of the opposite operator instead.

= and != use typed comparison: if the right-hand side parses as a number, numeric comparison is used; otherwise, case-insensitive string comparison. This means Amount=0 does numeric equality and Status=Pending does string equality — matching intuition with zero extra syntax.

Before numeric comparison, $ and , are stripped from both the cell value and the filter value. This handles financial formats like $1,200.00 automatically.

Values can be quoted with " or ' to handle spaces and special characters:

Terminal window
--where 'Entity Name="Affinity House Inc"'
--where "Category='Food & Drink'"

Column names are matched case-insensitively and after trimming whitespace from header cells. A header like " Status " matches --where Status=Pending.

When a numeric operator (<, >, or numeric =/!=) encounters a cell that doesn’t parse as a number (including empty cells), the row doesn’t match. After output completes, a one-line note is printed to stderr:

note: 3 rows skipped (Amount not numeric)

Use --quiet to suppress these notes in pipelines.

Rename header columns. Requires --headers. Comma-separated OLD:NEW pairs. Column names are matched case-insensitively.

Terminal window
# Rename two columns
vgrid convert vendor_export.csv -t csv --headers \
--rename 'order_number:Invoice,total:Amount'
# Rename + select (rename applies first, so use the new names in --select)
vgrid convert vendor_export.csv -t csv --headers \
--rename 'order_number:Invoice,total:Amount' \
--select 'Invoice,Amount'
# Align schemas before diffing
vgrid convert right.csv -t csv --headers \
--rename 'order_number:Invoice' -o right_fixed.csv
vgrid diff left.csv right_fixed.csv --key Invoice --compare Amount

Order of operations: parse -> --rename -> --where filter -> --select projection -> write. This means --where and --select use the new column names after renaming.

Unknown column names exit with code 2 and list available headers.

Select and reorder output columns by name. Requires --headers. Comma-separated values within a single --select arg are split, or use repeated --select flags.

Terminal window
# Pick two columns, reorder them
vgrid convert data.csv -t csv --headers --select 'Status,Amount'
# Equivalent repeated form
vgrid convert data.csv -t csv --headers --select Status --select Amount
# Filter by one column, output different columns
vgrid convert data.csv -t csv --headers \
--where 'Status=Pending' --select 'Amount,Vendor'
# JSON output contains only selected fields in --select order
vgrid convert data.csv -t json --headers --select 'Status,Amount'
# Pipeline: select then diff
vgrid convert data.csv -t csv --headers --select 'Status,Amount' | \
vgrid diff - expected.csv --key Status

Order of operations: parse -> --where filter -> --select projection -> write. --where can reference columns not in --select (filtering happens before projection).

JSON output contains only the selected fields, emitted in --select order (insertion order, preserved by common tooling).

Column names are matched case-insensitively and after trimming whitespace, consistent with --where. Unknown column names exit with code 2 and list available headers. Duplicate columns in --select exit with code 2. Ambiguous headers (two columns that collide under case-insensitive matching) exit with code 2 for both --where and --select.

For -t lines, --select outputs the first selected column (lines format is inherently single-column).

FormatExtensionsReadWrite
csv.csvyesyes
tsv.tsvyesyes
json.jsonyesyes
linesyesyes
xlsx.xlsx, .xls, .xlsb, .odsyes
sheet.sheetyesyes

When reading from a file, the format is inferred from the extension. Use --from to override or when reading from stdin.