$ cisiviv1.0.1Cisivi
A small CSV query tool and C library for macOS, Linux, and Windows. Query, filter, sort, and edit CSV files from the command line, so your shell scripts handle quoted commas and line breaks without cut or awk.
# Install with npm (or Homebrew, Scoop, packages).
$ npm install -g @partoska/cisivi# Read one column.
$ cisivi name crew.csvKirkSpockMcCoy, LeonardJaneway# Count the rows that match.
$ cisivi -c -f ship=Enterprise . crew.csv3# Change a value in the file.
$ cisivi -w -s Admiral -f name=Kirk rank crew.csvWhy Cisivi?
Small and Dependency-Free
One C99 tool and one C99 library that need nothing but the standard C library. Builds with GCC, Clang, or MSVC and runs from a Raspberry Pi to a Windows desktop.
Query What You Need
Ask for the whole table with ., columns by name or by position with #N, rows with [ROWS], or one value with [0].name. Rows also count from the end.
Filter and Sort
Keep the rows you need with the -f parameter: = for text, < or >= for numbers, ~ to search inside. Order them with --sort, numbers by value.
Real CSV, Not Split Lines
Quoted commas, doubled quotes, and line breaks inside values stay in one field. Counts with the -c parameter and column names with the -k parameter count records, not lines.
Output for Scripts and People
Print CSV, raw values one per line, JSON with the -j parameter, or an aligned table with the -t parameter. The -0 parameter ends values with NUL for xargs -0.
Any Delimiter
Read semicolons, tabs, or any other character with the -F parameter and write another with --output-delimiter. LF or CRLF, with or without a header row.
Join Several Files
Give several files and Cisivi joins them in order, matching columns by name. A column new in a later file is added, and rows that lack it leave it empty.
Set, Add, and Delete
Set values with the -s parameter, append or insert rows with the -a parameter, and delete rows or columns with the -d parameter. Print the result, or write it back to the file with the -w parameter.
Exit Codes for Scripts
0 found, 1 not found, 2 usage or input error. Output in CSV stays valid CSV, ready for another cisivi.
Ready for AI Agents
Cisivi ships with an agent skill. Install it with one command, and AI coding agents such as Claude Code and Codex can query and edit your CSV files with exact commands.
$ npx skills add partoska/cisiviOne Tool, One Library
The cisivi command is a thin layer over libcisivi. Use the command in shell scripts and pipelines, or link the library into your own C program.
Command-Line Tool
Reads files or standard input, prints exactly what a query selects, and edits values, rows, and columns. Made for shell scripts, Makefiles, and CI jobs.
$ cisivi -f ship=Voyager name crew.csvC Library
Reads and writes CSV with optional headers and any delimiter, with no type conversion. It keeps rows and columns in file order and never prints anything: errors are stored in the document with their line number.
#include <cisivi.h>Quick Start
Go from install to querying and changing a CSV file in five steps.
Install cisivi
Install the CLI and check the version. Prefer Homebrew, Scoop, or a native package? See the install options.
$ npm install -g @partoska/cisivi$ cisivi -VCreate a CSV file
Write a small table to try the queries on. Its first row names the columns. Any existing
.csvfile with a header row works too.$ printf 'name,rank,age\nKirk,Captain,34\n"McCoy, Leonard",Doctor,52\nJaneway,Captain,41\n' > crew.csvRead a column
Print the values of one column, then the whole table as an aligned table. The quoted comma stays in its value.
$ cisivi name crew.csv$ cisivi -t . crew.csvFilter and sort
Keep the rows where all filters hold, or sort the rows and take the first one.
$ cisivi -f rank=Captain -f 'age>40' name crew.csv$ cisivi --sort-desc age '[0].name' crew.csvChange a value
Set a value in the rows that match, write it back to the file with the
-wparameter, then read it again.$ cisivi -w -s Admiral -f name=Kirk rank crew.csv$ cisivi -f name=Kirk rank crew.csv
Examples
Print the whole table, columns by name or position, rows by position, or single values. Negative positions count from the end, and [N:M] takes rows from N up to M. Add the -i parameter to ignore the case of column names.
id,name,rank,age,ship1,Kirk,Captain,34,Enterprise2,Spock,Commander,35,Enterprise3,"McCoy, Leonard",Doctor,52,Enterprise4,Janeway,Captain,41,Voyager$ cisivi . crew.csv$ cisivi name crew.csv$ cisivi name,ship crew.csv$ cisivi '#1' crew.csv$ cisivi '[-1].name' crew.csv$ cisivi '[1:3].name,ship' crew.csv$ cat crew.csv | cisivi -i NAMEMore options are in the documentation.
Install
Pick the method that fits your system. Every option installs the same cisivi tool.
$ brew install partoska/tap/cisiviFor macOS and Linux on x64 and ARM64.
Commands use the latest version, 1.0.1. See the release page for all files and SHA256 checksums.
Add the AI Agent Skill
Let AI coding agents such as Claude Code and Codex run cisivi for you. The installer adds the Cisivi skill to the skills directory of your agent. In Claude, you can also upload cisivi_1.0.1_skill.zip from the release page as a custom skill. Install cisivi itself first.
$ npx skills add partoska/cisiviReference
Run cisivi [OPTIONS] [QUERY] [FILE...]. It reads every FILE in order, or standard input when there is none or the file is -. The query always comes first. Run cisivi -h for the built-in help.
Queries
- .
- The whole table, as CSV (default).
- COLUMN
- The values of one column, one per line.
- COLUMN,...
- Several columns, as CSV.
- #N
- A column by position, counted from 0.
- "NAME"
- A quoted column name, which may contain commas or quotes. Inside quotes,
\"and\\escape. - [ROWS]
- Rows by position, as CSV:
[N],[-N]from the end,[N:M]fromNup toM,[N:],[:M], or[*]. - [ROWS].COLUMN
- Rows and columns together, such as
[0].namefor one value.
Filter operators
- =, !=
- Equal or not equal, as exact text.
- <, <=, >, >=
- Ordered: numbers by value, other text byte by byte.
- ~, !~
- Contains the value, or does not.
Exit status
- 0
- Found, or the edit worked.
- 1
- Not found: a missing column, or no row selected. The header is still printed, so the output stays valid CSV.
- 2
- Usage or input error, including CSV syntax errors with their line on standard error.
Options
- -f, --filter EXPR
- Keep the rows where
COLUMN OPERATOR VALUEholds. Repeat it to require all. - --sort COLUMN
- Order the rows by
COLUMN, numbers by value. - --sort-desc COLUMN
- The same, in descending order.
- -k, --keys
- List the column names, one per line.
- -c, --count
- Print the number of rows selected.
- -s, --set VALUE
- Set the column of the query to the value in the selected rows, adding the column when missing.
- -a, --add ROW
- Append one record given as CSV text, or with
[N]insert it as rowN. - -d, --delete
- Delete the selected rows, or the columns the query names.
- -w, --write
- Write the edit back to
FILEinstead of printing it. Needs exactly one file. - -j, --json
- Print JSON: an array with an object per row.
- -t, --table
- Print an aligned table for reading.
- -0, --null
- End raw values and names with NUL instead of a newline.
- -F, --delimiter C
- Read fields separated by
C, such as;ortab. - --output-delimiter C
- Write fields separated by
C. By default, as read. - --crlf
- End written rows with CRLF instead of LF.
- -n, --no-header
- Read the first row as data. Columns are then addressed as
#N. - -i, --ignore-case
- Match column names case-insensitively (ASCII).
- -h, --help
- Show the help.
- -V, --version
- Show the version.
Library
- csInit, csDestroy
- Create and free a document. The flag
CS_FHEADERmakes the first row the header,CS_FICASEmatches names case-insensitively, andCS_FLFturns line breaks inside values into LF. - csLoad, csSave
- Load a document from a file, or save it to a file.
- csRead, csWrite
- Pull or push the text through your own callbacks: standard input, a socket, or memory.
- csParse
- Parse CSV text from a string.
- csGet, csSet
- Read or replace the value of a field by row and column. With a header, row 0 holds the column names.
- csRowAdd, csRowInsert
- Append a row, or insert one at a position.
csRowRemoveandcsRowRemoveManyremove rows. - csRowCount, csRowAt
- Count the rows, header included, and walk them in document order.
- csColumnFind, csColumnName
- Find a column by name, or get the name of one.
csColumnCountcounts them. - csColumnAdd, csColumnInsert
- Add a column filled with a value, or insert one at a position.
csColumnRemoveremoves one. - csSetDelimiter, csSetNewline
- Choose the field separator for reading and writing, and what ends written rows.
- csWriteRow
- Write a single record with the settings of a document, for rows produced one at a time.
- csError
- Get the last error with its status, line, and message.
See cisivi.h for the whole API. Include cisivi.h and link with pkg-config --cflags --libs cisivi.
Use Cases
Scripts and Operations
- →Read columns and values from CSV exports in shell scripts and CI jobs, where
cutandawkbreak on quoted commas. - →Filter, sort, and count the rows of reports, then print them as JSON for other tools or as a table for people.
- →Join monthly exports into one file, convert semicolon-separated spreadsheet exports, or update one value in place.
Development
- →Add CSV reading and writing to a C or C++ program with one small, dependency-free library.
- →Read CSV from memory, a socket, or standard input through stream callbacks, and write rows one at a time.
- →Let an AI coding assistant query and edit CSV files with exact commands instead of text edits.
Technical Specifications
Stop splitting CSV on commas.
Install Cisivi in one command and query your first CSV file in seconds.
View the source on GitHub, get the package on npm, read the documentation, or add the AI agent skill.