CSV Compare

Free + AI

Compare two CSV or TSV files row by row: rows matched by a key column wherever they sit, and every change named down to the cell. It runs in your browser.

Why compare CSV as data

Two exports of the same table seldom list their rows in the same order. Sort one by name and the other by date, and a line diff reports nearly every row as removed and added again, while the few rows that really changed look no different from the rest.

This page reads both files as tables. It matches rows by a key column (an id, sku or code header when there is one, the first column otherwise) and compares each pair of rows cell by cell under the column names. It opens on a price list exported twice, with the rows in another order and the thousands separators gone. What it reports is a new price, a new stock level, one row added and one removed, with the amounts that are only written differently set apart as formatting.

What it reports

Rows in a different order

id,name,plan
101,Asha,Pro
102,Ravi,Free
103,Meera,Team
id,name,plan
103,Meera,Team
101,Asha,Pro
102,Ravi,Pro

One change, at the cell /id=102/plan: Free to Pro. The rows were reordered, and that is not reported.

Same amount, written differently

invoice,amount
INV-7,"1,50,000.00"
INV-8,"12,400.00"
invoice,amount
INV-7,150000.00
INV-8,12040.00

One real change: INV-8 from 12,400.00 to 12040.00. INV-7 holds the same amount with and without lakh separators, so it is labelled formatting and not counted.

A column moved

sku,name,price
A-1,Cable,349
B-2,Hub,1299
sku,price,name
A-1,349,Cable
B-2,1299,Hub

One change, to the header row: the columns are in a new order. Cells are compared under their column names, so no row is reported as changed.

Options

Match rows by
Automatic picks a column named id, ID, key, code, sku or uuid, or one ending in _id, and falls back to the first column. Choose any other column from the list when the key is, say, an email address or an invoice number.
Number formats
A cell holding the same number written another way, such as 1,50,000.00 and 150000.00 or 1,000 and 1000.00, is labelled formatting and kept out of the count. A leading zero is never dropped this way: 01234 and 1234 stay different, as a postcode or an account number would.
Noise
Cells holding a timestamp, a UUID or a request ID that differs are labelled noise, so a last_synced column that changes on every export does not bury the edits.
TSV and semicolons
A file whose header is split by tabs is read as TSV, and one with semicolons and no commas, as spreadsheets set to a European locale often export, is split on the semicolon.

In a terminal

  • comm -3 <(cut -d, -f1 old.csv | sort) <(cut -d, -f1 new.csv | sort)

    Lists the keys found in only one file: at the margin if only in the old export, indented if only in the new. On this page's sample that is MS-220 removed and WC-330 added. cut -d, also splits inside quotes, so it is safe only while the key column comes before any quoted field.

  • comm -3 <(sort old.csv) <(sort new.csv)

    Prints every row that is not identical in both files, the old version at the margin and the new one indented. Sorting both first means row order stops counting.

What the page does that these do not
Neither reads the file as CSV: HD-510 and MN-270 show as changed rows because "1,299.00" became 1299.00, which the page calls formatting, and a changed row is printed whole where the page names the cell, such as stock for CB-001.
What the terminal does better
sort and comm get through exports far larger than the page's 5 MB a side: two files of 400,000 rows, 21 MB each, took under half a second.

Questions

Does row order matter?

No. Rows are matched by their key, so sorting either file differently changes nothing. Only a row whose key appears on one side alone is reported as added or removed.

What if two rows share a key?

They are paired in the order they appear: the first on the left with the first on the right, and so on. If the key column is not unique, choose one that is under Match rows by, or the pairing may not be the one you meant.

Is a changed header reported?

Yes, once, as a change to the header row. Cells are compared under their column names, so a column that only moved changes no row. A renamed column is different: its cells lose their partner, so every row reports that column as changed.

Are spaces and capital letters in a cell compared?

Yes. A cell is compared exactly as written, so Asha and asha, or a value with a trailing space, count as changes. Numbers are the one exception: the same amount written with or without separators is labelled formatting.

Can I compare Excel files?

Save each sheet as CSV first (Save As, then CSV UTF-8 in Excel; File, Download, then CSV in Google Sheets) and paste or drop the two files. The page reads text, so an .xlsx workbook cannot be opened directly.

Is the data uploaded?

No. Both files are parsed and compared in your browser, which matters for exports full of customer names, emails and amounts. Nothing is sent unless you ask for the optional AI explanation, and then only the changes you tick, with email addresses and phone numbers masked, after you have seen the text.

Nothing you type leaves this page

The comparison runs entirely in your browser: nothing is uploaded to compare and no account is needed. The one exception is opt-in and visible. If you press Explain with AI, only the changes you ticked are sent, with secrets, email addresses and phone numbers masked first, and the page shows you the exact text before it goes. The explanation keeps change numbers and its own wording, not your text.

Credits are a licence to use these tools - not money, not transferable. Full detail in our privacy policy and AI policy.