ConfigsApr 15, 2026·2 min read

q — Run SQL Directly on CSV, TSV, and Log Files

q (harelba/q) runs full SQLite-compatible SQL queries against CSVs, TSVs, and any delimited text file on disk — turning ad-hoc log digging into a one-line SQL statement.

TL;DR
CLI tool that runs SQLite-compatible SQL queries against CSV, TSV, and any delimited text file without database setup.
§01

What it is

q is a command-line tool that lets you run full SQLite-compatible SQL queries directly against CSV, TSV, and any delimited text file on disk. Instead of importing data into a database or writing awk/sed pipelines, you write SQL and q handles parsing, column detection, and query execution. It supports JOIN operations across multiple files, aggregations, and subqueries.

q targets data analysts, SREs, and developers who frequently analyze structured text files. It is particularly useful for one-off log analysis, CSV exploration, and quick data investigations where setting up a database would be overkill.

§02

How it saves time or tokens

q eliminates the database import step for ad-hoc queries. Instead of creating a table, loading data, querying, and cleaning up, you write a single SQL statement against the file. For log analysis during incidents, this means getting answers in seconds rather than minutes. JOIN operations across multiple CSV files replace multi-step shell pipelines with a single readable query.

§03

How to use

  1. Install q:
brew install q
  1. Run a SQL query against a CSV file:
q -H -d , "SELECT SUM(amount) FROM orders.csv WHERE status = 'paid'"
  1. Join multiple files:
q -H -d , "SELECT o.id, c.email FROM orders.csv o JOIN customers.csv c ON o.cid = c.id"
§04

Example

Analyze web server access logs with SQL:

# Top 10 IPs by request count
q "SELECT c1 as ip, COUNT(*) as hits FROM access.log GROUP BY c1 ORDER BY hits DESC LIMIT 10"

# 404 errors in the last hour
q "SELECT c7 as path, COUNT(*) FROM access.log WHERE c9 = '404' GROUP BY c7 ORDER BY 2 DESC"

# Join access logs with a blocklist CSV
q -H "SELECT a.c1, b.reason FROM access.log a JOIN blocklist.csv b ON a.c1 = b.ip"

Columns without headers are referenced as c1, c2, c3, etc.

§05

Related on TokRepo

§06

Common pitfalls

  • Without the -H flag, q treats the first row as data, not headers. Always use -H for CSV files with header rows.
  • The -d flag sets the delimiter. Forgetting it for CSV files (default is whitespace) produces incorrect column parsing.
  • q loads the entire file into memory for query execution. Files larger than available RAM will cause out-of-memory errors. Use streaming tools for very large files.

Frequently Asked Questions

What SQL dialect does q support?+

q uses SQLite's SQL dialect. This includes SELECT, WHERE, GROUP BY, HAVING, ORDER BY, JOIN, subqueries, and most SQLite functions. Window functions and CTEs are supported in newer versions.

Can q join multiple CSV files?+

Yes. q supports JOIN operations across multiple files. Use standard SQL JOIN syntax with file paths as table names. This replaces multi-step pipelines of grep, awk, and paste with a single SQL statement.

Does q modify the original files?+

No. q only reads files and outputs query results. It never modifies the source files. All operations are read-only, making it safe to use on production log files.

How does q handle files without headers?+

When files lack headers (or when -H is not used), q assigns automatic column names: c1, c2, c3, etc. You reference these in your SQL queries. For files with headers, use -H to enable named columns.

Is q faster than importing data into a database?+

For one-off queries, yes. q eliminates the import step entirely. For repeated queries on the same data, a proper database with indexes will be faster. q is designed for ad-hoc analysis, not recurring workloads.

Citations (3)

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets