Installation • Quick start • Commands • Formats • Options • Examples • Piping
nail - Lightning-Fast Data Analysis CLI
nail is a high-performance command-line tool for analyzing, transforming, and exploring Parquet, CSV, JSON, JSON Lines, Arrow IPC, and Excel files. Built with Rust, Apache Arrow, and DataFusion.
- Fast — gigabyte-scale datasets in seconds, parallel across all CPU cores.
- SQL-powered — DataFusion under the hood, familiar filter and expression syntax.
- Zero configuration — formats are detected from the file extension, on input and output.
- Composable — every command reads stdin and writes stdout, so
nailpipes into itself and other tools. - Self-contained — a single binary that works offline.
Installation
Prebuilt binary (macOS/Linux — auto-detects your OS and architecture):
curl -fsSL https://raw.githubusercontent.com/Vitruves/nail-parquet/main/install.sh | sh
It installs to /usr/local/bin when writable, otherwise to ~/.local/bin. Set BINDIR to choose the location explicitly, and the installer tells you if the target dir is not on your PATH:
curl -fsSL https://raw.githubusercontent.com/Vitruves/nail-parquet/main/install.sh | BINDIR="$HOME/bin" sh
With Cargo:
cargo install nail-parquet
From source:
git clone https://github.com/Vitruves/nail-parquet
cd nail-parquet
cargo build --release
sudo cp target/release/nail /usr/local/bin/
nail --help
With nix:
nix shell nixpkgs#nail-parquet
Dependencies: macOS — none. Linux — pkg-config and openssl.
Quick Start
nail describe sales.parquet # what is in this file?
nail head sales.parquet -n 5 # look at a few rows
nail filter sales.parquet -c "revenue > 1000" -o big.parquet # keep what matters
nail convert big.parquet -o big.csv # hand it to another tool
The package is nail-parquet on crates.io; the executable is nail.
Commands
append Concatenate multiple datasets
binning Bin continuous variables into categories
convert Convert between file formats
correlations Calculate correlation matrices
count Count total rows
create Create new columns with expressions
dedup Remove duplicate rows or columns
describe Show global file overview and metadata
diff Compare two datasets and show differences
drop Remove columns or rows
fill Fill missing values
filter Filter rows by conditions
frequency Calculate frequency distributions
head Display first N rows
headers Display column headers
id Add unique identifier column
merge Join two datasets
metadata Show Parquet file metadata
optimize Optimize Parquet files for better performance
outliers Detect outliers in data
pivot Create pivot tables with aggregations
preview Preview random N rows
rename Rename columns
sample Extract data samples
schema Display schema information
search Search for values in data
select Select specific columns or rows
shuffle Randomly shuffle rows
size Show data size information
sort Sort data by columns with various strategies
split Split data into multiple files
stats Calculate descriptive statistics
tail Display last N rows
transpose Transpose rows and columns
unique List distinct rows or per-column value counts
update Check for newer versions
help Print this message or the help of the given subcommand(s)
Run nail <command> --help for full usage.
Supported Formats
Formats are detected from the file extension on both input and output, and can be forced with -f/--format.
| Format | Extensions | Read | Write |
|---|---|---|---|
| Parquet | .parquet |
yes | yes |
| CSV | .csv |
yes | yes |
| JSON (newline-delimited) | .json |
yes | yes |
| JSON Lines | .jsonl, .ndjson |
yes | yes |
| Arrow IPC / Feather v2 | .arrow, .ipc, .feather |
yes | yes |
| Excel | .xlsx |
yes | yes |
Both Arrow IPC flavours are read: the file format (ARROW1 magic + footer) and the stream format written by e.g. HuggingFace datasets.save_to_disk. Writes always produce the self-contained file format.
nail head dummy_dataset/data-00000-of-00001.arrow
nail convert dummy_dataset/data-00000-of-00001.arrow -o dummy.jsonl
nail filter events.jsonl -c "status == 'error'" -o errors.arrow
Global Options
Available on all commands:
| Flag | Description |
|---|---|
-v, --verbose |
Timing and progress output |
-j, --jobs N |
Parallel jobs (default: all CPU cores) |
-o, --output FILE |
Output file, or - for stdout (prints a table to the console if omitted) |
-f, --format FORMAT |
Output format: json, jsonl, csv, parquet, arrow, text, xlsx |
--batch-size N |
DataFusion batch size (rows per record batch) |
--table |
Display console output as a columnar table instead of cards |
--random N |
Random seed for reproducible results |
--compression CODEC |
Parquet output codec: snappy (default), gzip, zstd, brotli |
--compression-level N |
Compression level (1-9) for gzip/zstd/brotli |
--color WHEN |
Colorize console output: auto (default), always, never (also honors NO_COLOR) |
-h, --help |
Command help |
Examples
Explore a dataset:
nail describe sales.parquet
nail stats sales.parquet -c "revenue,profit" --percentiles "0.5,0.9,0.99"
nail correlations sales.parquet -c "price,volume,discount" --tests t_test
nail frequency sales.parquet -c "category,region"
Clean and enrich:
nail dedup raw.parquet --row-wise -c "id" -o unique.parquet
nail outliers unique.parquet -c "price" --method iqr --remove -o cleaned.parquet
nail create cleaned.parquet --column "margin=(price-cost)/price" -o enriched.parquet
Build an analysis pipeline:
nail optimize raw.parquet -o opt.parquet --compression zstd --sort-by "ts,customer_id" --dictionary
nail binning opt.parquet -c "age" -b "18,25,35,50,65" --method custom --labels "18-24,25-34,35-49,50-64,65+" -o binned.parquet
nail pivot binned.parquet -i "age_binned" -c "category" -l "revenue" --agg sum -o summary.parquet
nail stats summary.parquet --stats-type exhaustive -o summary_stats.json
Reshape and summarize:
nail unique sales.parquet -c "category" # distinct values of a column
nail unique sales.parquet -c "category,region" --count # value counts, most frequent first
nail transpose metrics.parquet --header-column metric -o wide.parquet
Compare versions:
nail diff yesterday.parquet --compare today.parquet --keys "id" --changes-only
Piping (stdin/stdout)
Every command can read from stdin and write to stdout, so you can chain nail with itself or other tools. Use -o - on the producer to stream out, and - as the input on the consumer to read in. The input format is auto-detected.
Streaming to stdout defaults to Parquet, which preserves the full schema (types and nested List/Struct/Map columns) losslessly across the pipe. Use -f csv or -f json when you want text output for other tools.
# chain nail commands (Parquet by default — keeps all types)
nail filter sales.parquet -c "revenue > 1000" -o - | nail sort - -c revenue -o - | nail head - -n 10
# stream as CSV/JSON for other tools
nail select sales.parquet -c "id,revenue" -o - -f csv | grep -v '^0,'
nail sample sales.parquet -n 100 -o - -f json | jq '.revenue'
# read from stdin produced elsewhere
cat data.parquet | nail count -
Pipes that close early (| head, | less) are handled cleanly — no broken-pipe errors.
Performance Tips
- Prefer Parquet over CSV for analytical workloads.
- Scope operations with
-cregex patterns. - Use intermediate files for multi-step transforms.
- Tune
-jto match your machine. - Add
--verboseto monitor long runs.
License
MIT — see LICENSE.
Contributing
Fork, branch, add tests, ensure cargo test and cargo clippy pass, open a PR.
Support
Issues and questions: https://github.com/Vitruves/nail-parquet/issues
Metadata
Release files for nail-parquet 1.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nail_parquet-1.9.0.tar.gz | 297.5 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| nail_parquet-1.9.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| nail_parquet-1.9.0-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| nail_parquet-1.9.0-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| nail_parquet-1.9.0-py3-none-manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64 | Details |
| nail_parquet-1.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| nail_parquet-1.9.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| nail_parquet-1.9.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 102.5 MB
Release files / nail_parquet-1.9.0.tar.gz
| Download URL | nail_parquet-1.9.0.tar.gz |
|---|---|
| Size | 297.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
84ab006dc50d7522eb23ec149b12fba747781863e0a9923365e717c2f23e823b
|
|
BLAKE2b-256 checksum How to use checksums |
83537fd4ad65cbef604f959b9c4b3fefa5ca636dc8731aa39af23d6fea90899c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-win_amd64.whl
| Download URL | nail_parquet-1.9.0-py3-none-win_amd64.whl |
|---|---|
| Size | 14.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
da3816e709c24b896192a70369bcd39b6b72ae0a991826c045464fcd4e0064ad
|
|
BLAKE2b-256 checksum How to use checksums |
69cba51deb19529e514c882beb5c901087e863ca3ab22592c7978c0893fe0cc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-musllinux_1_2_x86_64.whl
| Download URL | nail_parquet-1.9.0-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 15.7 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
63526b3ab3a1dcfb454189a287d9bb9a08a7bd7ea8c6d935acfafb39bc7d7ff9
|
|
BLAKE2b-256 checksum How to use checksums |
80370f053101631453c3df08b6e7f22a9addf4b2f16250854834bc9834621353
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-musllinux_1_2_aarch64.whl
| Download URL | nail_parquet-1.9.0-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 14.3 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
aae2b707373d3c5cce9098f32eb84352319b77b0c12a2c157a037258c85fc7bf
|
|
BLAKE2b-256 checksum How to use checksums |
52a445f6a22d85f7e236dc05ce4e87553b74b32a54a3726191c226655fb04f69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-manylinux_2_28_aarch64.whl
| Download URL | nail_parquet-1.9.0-py3-none-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 14.5 MB |
| Tags | Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
b653e17e97417590137be07f743de2a9b99a0b455896e06fe7ab1543a4ba93da
|
|
BLAKE2b-256 checksum How to use checksums |
f2d0d140e02af67b73dfe8ef5f0454dc33a8371e9b093c0fea7c72003e47fa8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | nail_parquet-1.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 15.5 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
7cae1c3b865be3c36520854fb57705f8ca7c85fa6f8077f16d22fa72132d03c9
|
|
BLAKE2b-256 checksum How to use checksums |
2d4d9a74c20949cc7f033d9a4aee7a9d7f5676c6c5572cc70e325358a24e3e5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-macosx_11_0_arm64.whl
| Download URL | nail_parquet-1.9.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 13.1 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
6f5cf73a5d1cdffb64bc5f71446a9d094b08a475ebf49db33cf34d4bc4156700
|
|
BLAKE2b-256 checksum How to use checksums |
420fa2d06ab7e12ba8388899a9bb6407ab8047e8db7e0cb10d1a7da556bd6973
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / nail_parquet-1.9.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | nail_parquet-1.9.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 14.6 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
d1ab0c6fe22ba15681f0c254cfb37ec9aabec4f61fdb42b5c9dc3a88a392cc5e
|
|
BLAKE2b-256 checksum How to use checksums |
26c0559f2bda5a5ddc577699379b55a453aa71cee194fee81fe885dfee1ebfbf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency log