# csvtk gives you 59 subcommands for the CSV surgery you would write in Python

> csvtk is a cross-platform Go toolkit of 59 subcommands for inspecting, converting, filtering and summarising CSV and TSV files, with column-name selection, unselection and fuzzy matching, and support for compressed input and output. It fits a bioinformatician or data analyst who wants the same table operation in a shell pipeline every time, and it does not fit a project that needs a library API inside an application.

**shenwei356/csvtk** — A cross-platform, efficient and practical CSV/TSV toolkit in Golang

- Repository: https://github.com/shenwei356/csvtk
- Website: http://bioinf.shenwei.me/csvtk
- Stars: 1,173 · Forks: 95
- Language: Go
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shenwei356-csvtk

## The problem is that every dataset needs the same three operations

csvtk describes itself as a cross-platform, efficient and practical CSV/TSV toolkit in Golang, and the Introduction gives the reasoning in a way that is worth quoting because it explains the whole category of tool.

CSV and TSV formats are basic and ubiquitous in both bioinformatics and data science, comparable to the way FASTA/Q is basic in bioinformatics. People usually use spreadsheet software like MS Excel to process table data, but that is all by clicking and typing, which is not automated and is time-consuming to repeat, especially when you want to apply similar operations with different datasets or purposes.

The alternative people reach for is shell commands, but the README is specific about the two gaps: more code is needed to handle the header line, and shell commands do not support selecting columns with column names.

Those two gaps are the design brief for the whole tool. Every subcommand that takes a -f flag accepts a field specification in terms of header names rather than column numbers, and the field selection is the most reused idea in the package.

The stated purpose is convenient for rapid data investigation and also easy to integrate into analysis pipelines, and the README says it could save you lots of time in not writing Python or R scripts. That is the honest pitch: it is a way to stop rewriting the same table code.

The last push was on 2026-10-15, the newest release is v0.38.0 from 2026-09-24, and the licence is MIT.

## Field selection by name, with unselection and fuzzy matching

The feature that distinguishes csvtk from a pile of awk one-liners is the field specification, and the README describes three forms of it. Most of the subcommands support unselecting fields and fuzzy fields, for example -f "-id,-name" for all fields except id and name, and -F -f "a.*" for all fields with the prefix a.

The unselection form is the one that changes how you write the command. Specifying fields by name means the command keeps working when someone reorders the columns or inserts a new one upstream, which is the normal way table scripts break. The fuzzy form, with a regular expression, handles the case where the interesting fields share a prefix, which is common in bioinformatics output where every column might be prefixed with the sample name.

The -F flag is the fuzzy counterpart of -f, so the exact and the pattern form are separate flags rather than one flag with two syntaxes. That is a small design decision with a practical effect, since a field name containing characters that would be ambiguous in the fuzzy syntax does not need escaping in the exact one.

The subcommand list is grouped by what it does to the data, and the grouping tells you what the tool is for. Information commands cover headers, dim, nrow, ncol, summary, watch and corr, where summary gives statistics of selected numeric or text fields with a groupby, watch does online monitoring and a histogram of a selected field, and corr calculates Pearson correlation between numeric columns.

Format conversion commands cover pretty, csv2tab, tab2csv, space2tab, csv2html, csv2md, csv2rst, csv2json, csv2xlsx and xlsx2csv. The set operations cover head, concat, paste, sample, cut, grep, uniq, freq, inter and filter, where filter filters rows by values of selected fields with arithmetic expressions.

Fifty-nine subcommands in total, according to the README.

## Compression and stdin are handled, so it fits an existing pipeline

The pipeline claim only works if the tool composes with the rest of a shell pipeline, and two features make that true.

The first is stdin and gzipped input and output support, easy being used in a pipe. The second is seamless support for xz (.xz), zstd (.zst), Bzip2 (.bz2) and LZ4 (.lz4) formats.

Compressed input is not a small convenience in bioinformatics, where reference tables and sequence databases are routinely distributed gzipped and where a pipeline that decompresses to disk, processes and recompresses is a common source of temporary space problems. Reading .zst directly avoids the intermediate file entirely.

The other implementation detail worth noting is in the go.mod. The dependency set includes klauspost/pgzip and klauspost/compress, which are the gzip and general compression libraries, and github.com/xuri/excelize/v2 at 2.11.0 for the XLSX conversion, plus gonum.org/v1/gonum and gonum.org/v1/plot for the plot subcommands, with go-latex and go-pdf in the indirect set for the PDF output path. The Go version is 1.25.14.

Other dependencies show the shape of the feature set. expr-lang/expr at 1.17.8 is the expression engine, and casbin/govaluate at 1.10.0 is a second one, which is an unusual thing to see and suggests the two are used for different expression dialects. araddon/dateparse handles the date parsing in the summary and date-related subcommands, dustin/go-humanize formats the numbers in the summary output, cheggaaa/pb is the progress bar, and spf13/cobra provides the command tree.

## Installation offers a binary, Pixi, conda, homebrew, go get and the AUR

The installation section is the longest in the README, with six methods, and the range tells you who the audience is.

Method 1 downloads binaries, both the latest stable and the dev version, for Linux, Windows and Mac OS X. Method 2 installs via Pixi. Method 3 installs via conda, latest stable version, and the project is on conda-forge with a badge for it. Method 4 installs via homebrew. Method 5 is for Go developers, which means go install of the module. Method 6 is for Arch Linux AUR users, with the caveat that it may not be the latest.

The Pixi entry is worth noting because it is newer than the conda and brew entries and reflects a shift in how scientific tooling is distributed. The conda-forge presence matters more for the bioinformatics audience than the others, because a conda environment is already the norm in that field.

The library is built to be light weight and out-of-the-box, with no dependencies, no compilation and no configuration. That claim is about the binary, and it is consistent with a Go program that ships as a single file, in contrast to the Python tools it is positioned against, which need an interpreter and a package environment on every machine.

The project also documents command-line completion, which is the detail that separates a tool people use from a tool they try once.

## What csvtk does differently from the alternatives

The README has a section titled Compared to csvkit, and that is where the project states its differences in approach, so it is the right place to look rather than guessing.

The two approaches the README itself contrasts are the alternatives most people actually have. Spreadsheet software, which is manual, not automated, and not repeatable without clicking. And shell commands, which need more code to handle the header line and cannot select columns by name. csvtk's whole design is a third option: a single binary where column selection is by name, which is what makes the operations repeatable across datasets.

There is also a plot subcommand set, described as support for some common plots, with the usage page as the reference. That is a deliberate addition over a pure filter-and-convert tool, and it is the kind of feature that decides whether you need a second tool in the pipeline.

One item in the feature list is struck through in the README. Seamless support for data with a meta line, for example sep=,, of separator declaration used by MS Excel, is marked as removed. That is a small but telling detail, because the meta line is an Excel-ism that a well-formed CSV should not contain, and the project decided that carrying the compatibility was not worth it.

## Where csvtk is the wrong tool

The first wrong-tool case is an application that needs table manipulation as a library. csvtk is a command line program with 59 subcommands, and the go.mod defines the module github.com/shenwei356/csvtk, but the value is in the commands rather than in an importable API. A service that needs to filter and join tables at runtime wants code it controls, not a subprocess it shells out to.

The second is a schema-heavy workflow. A file with a defined schema, a primary key, foreign keys and update semantics belongs in a database, and a table toolkit will not give you those constraints however many subcommands it has. csvtk works on files, and files have no schema enforcement.

The third is the scale boundary. The README says it is fast and that some commands support multiple CPUs, and it is a compiled Go binary, so it handles large files far better than a Python script would. But the operations are row-at-a-time or field-at-a-time over files held in memory or streamed, and the design assumes the whole table fits comfortably in a machine. A dataset that does not fit is a different problem, and one that a tool with a small in-memory model is the wrong answer to.

The fourth is the value of a bespoke script. For a single dataset with one unusual operation, a short Python or R script is faster to write, easier to review and does not need anyone to learn csvtk's field specification syntax. csvtk pays off when the same handful of operations run across many datasets, and the README says exactly that.

## Conclusion

csvtk fits a researcher or analyst who repeats the same table operations across datasets and wants a single binary instead of a growing pile of Python or R scripts. It does not fit a service that needs table manipulation as a library dependency, and it does not fit a schema-heavy workflow where a proper database would be the right tool. Before adopting it, read the Compared to csvkit section on the project site, because the README points there for the differences in approach, and note that the tool is a command line program rather than an importable package.

## FAQ

### What is csvtk and how many subcommands does it have?

csvtk is a cross-platform Go toolkit for CSV and TSV files, described as light weight and out-of-the-box with no dependencies, no compilation and no configuration. The README states there are 59 subcommands in total, grouped into information, format conversion and set operations.

### How do I select columns by name in csvtk?

Most subcommands support unselecting fields and fuzzy fields. The examples given are -f "-id,-name" for all fields except id and name, and -F -f "a.*" for all fields with the prefix a., so the exact selection uses -f and the regular expression form uses -F.

### Which compression formats can csvtk read and write?

The feature list states seamless support for xz (.xz), zstd (.zst), Bzip2 (.bz2) and LZ4 (.lz4) formats, along with support for STDIN and gzipped input and output so it can be used in a pipe.

### How do I install csvtk?

There are six documented methods: downloading binaries for the latest stable or dev version, installing via Pixi, installing via conda from conda-forge, installing via homebrew, installing as a Go developer, and installing from the Arch Linux AUR, which may not be the latest version.

## Sources

- [License: MIT](https://github.com/shenwei356/csvtk/blob/master/LICENSE)
- [Project website](http://bioinf.shenwei.me/csvtk)
- [README](https://github.com/shenwei356/csvtk/blob/master/README.md)
- [Releases](https://github.com/shenwei356/csvtk/releases)
- [shenwei356/csvtk on GitHub](https://github.com/shenwei356/csvtk)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shenwei356-csvtk
