SQL for Markdown Tables

Warning: This is an experimental program that modifies files in-place. Always use version control (git) or back up your markdown files before running INSERT or DELETE operations.

mdsql treats tables in markdown files as a lightweight database. Query, insert, and delete rows using familiar SQL syntax while keeping your data human-readable.

The idea is simple: markdown tables are already structured data. Why not query them like a database? This gives you the best of both worlds, files you can read and edit by hand, with the power of SQL when you need it. The SQL itself never includes filesystem paths; the file stays a CLI argument.

GitHub

Install

Install with Cargo:

cargo install mdsql

Quick Start

Given a markdown file with a table:

# Team

| name    | role      | level |
|---------|-----------|-------|
| Alice   | Engineer  | 3     |
| Bob     | Designer  | 2     |
| Charlie | Manager   | 4     |

List tables in a file:

$ mdsql tables team.md
Table 0: 3 columns, 3 rows
  Columns: name, role, level

Query with SQL:

$ mdsql query "SELECT name, role FROM 0 WHERE level > 2" team.md
name     role
Alice    Engineer
Charlie  Manager

Supported SQL

SELECT

# Select all columns
mdsql query "SELECT * FROM 0" data.md

# Select specific columns
mdsql query "SELECT name, age FROM 0" data.md

# Filter with WHERE
mdsql query "SELECT * FROM 0 WHERE status = 'active'" data.md

# Sort results
mdsql query "SELECT * FROM 0 ORDER BY score DESC" data.md

# Limit results
mdsql query "SELECT * FROM 0 LIMIT 10" data.md

# Combine clauses
mdsql query "SELECT name, score FROM 0 WHERE score > 50 ORDER BY score DESC LIMIT 5" data.md

INSERT

# Insert a new row
mdsql insert "INSERT INTO 0 (name, role, level) VALUES ('Diana', 'Engineer', '2')" team.md

DELETE

# Delete matching rows
mdsql delete "DELETE FROM 0 WHERE name = 'Bob'" team.md

# Delete all rows (use with caution)
mdsql delete "DELETE FROM 0" team.md

UPDATE

# Update matching rows
mdsql update "UPDATE 0 SET role = 'Lead' WHERE name = 'Alice'" team.md

Output Formats

Use --format to change output:

# Column-aligned (default, like df -h)
mdsql query "SELECT * FROM 0" data.md

# Markdown table
mdsql query --format markdown "SELECT * FROM 0" data.md

# CSV
mdsql query --format csv "SELECT * FROM 0" data.md

# JSON
mdsql query --format json "SELECT * FROM 0" data.md

# Tab-separated
mdsql query --format tsv "SELECT * FROM 0" data.md

Unix Pipelines

The default column output works well with standard Unix tools:

# Count rows matching a condition
mdsql query "SELECT * FROM 0 WHERE status = 'active'" data.md | tail -n +2 | wc -l

# Filter output with grep
mdsql query "SELECT * FROM 0" data.md | grep "Engineer"

# Process with awk
mdsql query "SELECT name, score FROM 0" data.md | awk 'NR>1 {sum+=$2} END {print sum}'

Table Addressing

Tables are addressed by their 0-based index in the document. The first table is FROM 0, the second is FROM 1, and so on.

# Query the first table
mdsql query "SELECT * FROM 0" data.md

# Query the second table
mdsql query "SELECT * FROM 1" data.md

Roadmap