Features

Every feature, in one place.

160 of the things Intact CSV Editor does, from reading a file's dialect to exporting a PDF/A. All of them keep the promise: what you did not change, stays as it was.

Opening files

Every file opens as a table, and the app says what it found.

The dialect of a text file is worked out when it opens — and every part of it is shown in the Format inspector, where it can be corrected. Anything the app had to guess is said plainly, with how sure it was.

Separators of every kind

Comma, semicolon, tab, pipe, colon, space, the ASCII unit separator, or any string you type.

Quoting and escaping

Double quotes, single quotes or none; quotes escaped by doubling them or with a backslash.

Line endings

LF, CRLF, CR — and files that mix them, which are read rather than refused.

133 character sets

81 text encodings — every Unicode form, the Windows and ISO code pages, the classic Mac scripts, DOS pages and East Asian multi-byte encodings — and 52 EBCDIC code pages.

Every character set, side by side

When the reading is in doubt, every character set that can read the file is listed with how well it fits, each showing the first line with accents in it — Łódź or £ódŸ settles it at a glance.

Two encodings in one file

Exports stacked together are often UTF-8 in one half and Windows-1252 in the other. Each character is read as what its own bytes can only be, and the inspector says the file needed it.

Header rows and comments

A header row is recognised by comparing the first row's types with the rest. Comment lines are remembered and written back where they were.

Awkward files

Ragged rows, stray quotes, unterminated quotes and blank lines are read, not rejected. The cells a short row never had are hatched, so they are not mistaken for empty values.

Recognised by bytes, not by name

A workbook saved as export.dat still opens as a workbook; an ORC file is known by its first bytes.

Workbooks and databases

An .xlsx, .xlsm, .xls, .xlsb or .ods asks which sheet to open, a SQLite file which table — and the window says what else the file holds.

Open part of a file

The first megabytes, the last, or a stretch from any point — cut where records begin and end, with the header line put in front. Only that part is read from the disk.

Follow a file as it grows

Rows another program writes onto the end come into the table as they arrive, the way tail -f follows a log, and the grid stays at the end if you were reading there.

Quick Open

⌃⌘O and a few letters of a name: the files open now, the recent ones and the tables in the folder you last browsed. ⇧⌘T reopens the file you just closed.

Open from a link

Paste an address and the file is downloaded and opened as a table. Only an address you typed or picked is ever fetched.

The clipboard as a table

⇧⌘V opens whatever is on the clipboard as a new table — a block from a spreadsheet, a table from a web page or Word, JSON, a Markdown table.

A folder of tables

One window lists every file in a folder the app can read — name, size, date — searchable, and one Return from being open.

Rules for where files live

Tell the app once that ~/Exports/DE holds semicolon files in Windows-1252, and detection is set aside for them.

Formats you name and keep

The export from one system is semicolons in Windows-1252 without quotes: keep that as a named format, choose it from the menu next time, or have new files start in it.

Log files by pattern

A regular expression describes a line; each capture group becomes a column. Lines that do not match are counted, never dropped quietly.

Editing

Spreadsheet speed, without a spreadsheet's opinions.

Type, fill, drag and paste the way you would in a spreadsheet — and the file still gets back exactly what you typed, with no curly quotes, no dates made up and no numbers reformatted.

Type over a cell

A printable key replaces the selected cell's value; Tab and Return move on. The column's own values are offered as you type.

Fill handle and series

Drag the corner of a selection, or choose Fill with a Series…: numbers step or multiply, dates move by days, working days, months or years, weekdays and your own lists run on — and 007 continues as 008.

Several cursors, the grid's way

⇧⌥↩ opens the focused cell, and the change you make there is made at the same place in every selected cell — a space after the third digit of every phone number, in one step.

Select as you think

Blocks, whole rows and columns, several blocks at once with holes in them, every match of a search — and invert any of it.

Move rows and columns

Drag them by their number or heading, move them with the keyboard like lines in Xcode, or send them to a numbered position.

Change the selected cells

Text in front or after, leading zeros off or on, decimals, the first or last characters, acronyms, random numbers, dates, UUIDs (version 7 included) — and Base64, percent-encoding, HTML entities, Unicode forms and hashes.

Write dates another way

Read a column in one shape and write it in another — ISO 8601, day-first 08.01.2026, US, Unix seconds, Excel serials. What is not a date keeps its text.

Write numbers another way

Convert a selection between 1234.50, 1234,50, 1,234.50, 1.234,50 and 1'234.50, keeping the decimals each value had.

JSON and lists inside a cell

⌥⌘J edits a cell's JSON as a tree, keeping key order and numbers exactly as written. ⌥⌘L edits a; b; c as a list. JSON and XML format or minify in place.

Paste the way you mean

Paste transposed, paste as one plain value, or insert the copied rows and columns rather than writing over what is there. A table copied from a web page, Word or a PDF viewer arrives in its own cells.

Paste from History

The last twenty things copied in the app, newest first, with the ones you pinned kept across launches. Nothing a password manager marks as private is ever kept.

Copy as anything

A selection goes to the clipboard as Markdown, JSON, SQL, HTML, YAML, XML, LaTeX, AsciiDoc and more — rich text lands in Pages, Word or Mail as a table, and codes pasted into Excel keep their leading zeros.

Edit the file as text

View ▸ Edit the File as Text: mend a stray quote in the text itself, then read it back into the grid with ⌘↩ — one step of undo.

What changed since saving

Every cell edited since the last save has a wash behind it. Step from one change to the next, compare with the saved file, or put a single cell back as the file had it.

Show values as written

Each value drawn with the quotes and escapes the file will give it, in a colour of their own — the file's view of your table.

Show what cannot be seen

Tabs as ⇥, line breaks inside a value as ↵, non-breaking spaces as ␣ — drawn only, the file is untouched.

Record view

The focused row shown downwards as labelled fields, for tables wider than the window.

Rows as tall as they need

Drag one row's edge and only that row grows; double-click the edge of a heading and the column fits what is in it.

One table, two views

Split the view in two to read row 4 beside row 40,000, or column 3 beside column 70 — one table, two scroll positions.

History you can click into

Edit ▸ History lists every step by name, with the file as opened at the top. Click a step to go back to it, and forward again.

Find, filter and sort

Find the rows that matter, and put them in order.

Search with plain text or regular expressions, narrow the rows as you type, and sort by as many columns as you like — then put the file's own order back with one click.

Find and replace

Case, whole-cell and whole-word matching, regular expressions with $1 in the replacement, and a preview that lists every cell Replace All would touch.

Recent and saved searches

The find bar remembers what you looked for and keeps the searches you name, in every window.

List every match

Every match as a list to read, jump to and take away — and grouped by what a pattern's first group caught.

Replace using a table

Hundreds of find-and-replace pairs from a second table in one step, each pair with its own switches for case, whole word or pattern.

Find and replace in files

Look for a value in every table in a folder, then replace it file by file with a preview first and a .bak copy of each file beside it.

Markers

Light every cell that matches in one of six colours, in every window, and keep the markers for the next launch.

Select every match

Turn a search into a selection, then change all of it in one step — or add the next match one at a time.

Filter as you type

The toolbar box narrows the rows at once. Switch on patterns and it understands *abc*, !x, 50+, 0-10, & and |.

Conditions

is, contains, begins with, between, at least — read as numbers or dates where that is what they are, over one column or all.

A filter on every heading

The column's values, most common first, with counts and a search box — or two sliders for a range when the column holds numbers. The first click keeps only the value clicked.

Filter from a cell

Right-click a cell to keep only its value, exclude it, or keep what is greater or less than it.

Filter by a list

Paste or drop a list of values — customer numbers from an email — and keep or hide exactly those rows.

Filters you can see

Every filter in force is listed, one line each. Switch one part off to see the table without it, and on again; saved filters are offered in every window.

Sort by several columns

⇧-click headings to add them to the sort. Numbers sort as numbers, dates as moments in time, text the way your language reads it — Ärzte before Zug.

Sorts and orders kept

Keep a sort by name for next month's file, or sort by an order you write down — S, M, L, XL, or fourteen departments the way the report wants them.

The way back

A third click on a heading, or ⇧⌘U, puts the rows back in the file's own order — even after rows were edited, added or deleted.

Flags and notes

⌥-click a row number to flag it and write a note beside it. Flags survive sorting and filtering, come back when the file is opened again, and ⌘J walks through them.

Filter across a row

For tables written the other way round: hide the columns whose heading, or any row, does not match a pattern.

Clean-up

The tidying every exported file needs.

Most files that arrive from another system need the same few things done to them. Each one is a command, shows what it will do, and is one step of undo.

Duplicates judged on the columns that matter

Two rows with the same customer number are the same customer, whatever else differs. Select them first, or remove them — keeping the first copy of each, or the last.

Empty rows, columns and edges

Remove the blank rows and columns a spreadsheet export leaves at the bottom and right; a blank row in the middle is left alone.

Short and long rows

Select the rows written with too few or too many fields, and put a record back together where a line break cut it in two.

Values that look alike

Zurich, Zürich and ZURICH found as one group — by spelling, word order or a slip of the keys. Nothing is merged until you tick it.

Correct a column's values

Every distinct value in a column with how often it appears, editable in place: fourteen spellings of one status, tidied in a minute.

Text written twice over, put back

Zürich becomes Zürich again: text that went through the wrong encoding and back is repaired, with the changes shown before anything is written.

Spelling in a column

Check the spelling of a column of prose. A column of codes is recognised as codes and not marked up.

Trim and change case

Upper, lower, title, sentence, camel, Pascal, snake, kebab, UPPER_SNAKE, full-width and half-width — and straight quotes, single spaces and plain spaces where the export had others.

Split and join cells

Join across a row or down a column with any separator, split them apart again at a separator or at character positions, and close the gap a join leaves.

Reshape

Wide to long and back, and a cell of several values split into rows — with a count of anything that did not fit rather than a silent drop.

Escape sequences

Turn a written-out \n into a real line break, over a selection you choose — never automatically, because C:\new looks the same.

Headers over two rows

Turn the stacked header rows of a report into one name per column: Q1 over Revenue becomes Q1 Revenue.

Column names that work everywhere

Make the Column Names Usable turns Umsatz (CHF) 2026 into a name every database and script accepts — or rename and reorder every column from a pasted list.

Add an ID column

Number the rows into a column of their own, and renumber it rather than add a second one next time.

Keep what you need

A range of rows by number, a thousand rows at random for a sample, or the table cut to a set number of columns.

Analysis and charts

Answers without leaving the file.

Summaries, statistics, charts, lookups and comparisons — the questions a table is usually opened for, without writing a formula or a query.

Summarise

Group by one column, spread another across the top, and sum, average, count or take the median — with nested groups and subtotals, shown as the figure, its share of the whole or a running total.

Show the SQL

Every summary can show the statement it stands for and open it in the query console, so a summary is a starting point rather than a dead end.

Charts

Line, bars, pie or scatter from the columns that hold numbers. The pointer reads every value off the chart, and it saves as an SVG whose labels are still text.

Trend lines

Straight, exponential, logarithmic, power, a curve up to degree five, or a moving average — with the equation and R² written on the chart.

Charts inside the table

A bar column, a sparkline across twelve month columns, a win-or-loss column, a rank or a share of the total — made of characters, so they copy and export like any value.

Statistics

Every column counted: filled, empty, distinct, shortest and longest, and for numbers the median, spread and quintiles, drawn as bars. Two columns against each other give Pearson's r and the fitted line.

Subtotal rows

A line after each run of a column with every column of numbers added up, and a total at the end — the table with its totals in it.

Across the row

The sum, average or count of the columns you choose, into a column of its own.

Look values up in another table

Carry a customer's name and city over from another file by a key column, with a preview before anything is written.

Join two files

Inner, left, full or cross, on a key chosen on each side — with the rows that found no partner counted before you join.

Compare two files

Rows lined up by position or by a key, columns by name; changed values marked character by character and taken across one at a time. Or compare with the file as last saved.

The status bar adds up

Count, sum, average, minimum and maximum of any selection, each one a click away from the clipboard.

A summary row

Pin a sum, average, count, minimum or maximum under each column, over the rows on show.

Column inspector

A column's types, distinct and empty counts, minimum, maximum, sum and average at a glance — and the same facts when the pointer rests on its heading.

SQL

MySQL-flavoured SQL over every open file.

⇧⌘R opens a query window. Each open document is a table named after its file, and only the tables a statement names are loaded.

Join files

SELECT * FROM customers JOIN orders USING (customer_no) — a CSV with a workbook with a Parquet file.

Files that are not open

FROM "@file:/Exports/archive.csv" reads a file by its path.

Views

Save a query by name and it becomes a table you can query — and open as a document that is always current.

MySQL's vocabulary

Backticks, # comments, SHOW TABLES, DESCRIBE, GROUP_CONCAT … SEPARATOR, DATE_FORMAT, REGEXP and more than eighty of MySQL's text, number, date and JSON functions.

Scripts and dumps

Paste a MySQL dump as it stands: the preamble is dropped, CREATE TABLE is cleaned of what only a server needs.

Numbers people write

Columns that hold 1'234.50 or 987,25 become real numbers, so they compare and add up correctly.

Patterns that cannot run away

A regular expression that would take for ever on a long value is refused with the reason, rather than stopping the app.

Long results a page at a time

101–200 of 4,318, with a step either way — and a statement with its own LIMIT runs exactly as written.

From the result

Replace the table with the answer, export it to any format, or open it as a new document.

Automation

Do it once, then never again by hand.

Recipes for the clean-up every export needs, macros for the edits a click cannot make, programs for the ones another tool already knows, and AppleScript for the ones that start somewhere else.

Recipes

What Was Done to This File… records the steps you take — by column name, not position — and runs them on next month's export in one undoable go.

JavaScript macros

A small script over the selection or the whole table, in Tablecruncher's vocabulary. One step of undo; stopped after ten seconds if it runs away.

Run a program over the table

The table goes out as CSV on standard input; what comes back on standard output is read again. sort, awk, jq, a Python script — no shell involved.

One line per row

A template filled in once for every row, with escaping for SQL, JSON, HTML, web addresses and CSV — the statements, links or messages a table stands for.

Ask a web service about each row

One request per row to an address you write, the answers into a new column. The sheet shows the exact first request and the host before anything is sent.

AppleScript and Shortcuts

row count of table "sales", export table to "~/Desktop/sales.xlsx", run query "SELECT …".

The icsv command

icsv sales.csv --goto 120:3, psql -c '…' | icsv --header, and icsv convert ledger.sav --to ledger.parquet, which converts without a window.

intact-csv:// links

Open a file at a row and column, with a separator and encoding, from anywhere a URL works.

Workspaces

Keep the open files, each with its filter, under a name, and open them all again in one step.

Jobs

Window ▸ Jobs lists everything running in the background — a large file streaming in, an export, a search through a folder, a query — with a Stop for each.

The command palette

⇧⌘P finds any command by a few letters — rmdup finds Remove Duplicate Rows.

Your shortcuts

Rebind forty commands, including sequences like ⌃K then ⌃U.

Out to other apps

Search the web for a value with twelve engines or your own, find it on the map, or open a mail draft to the addresses in a selection — never sent for you.

Validation

Write down the rules a table has always had.

An ID that must be there and unique, an amount that is never negative, a status that is one of three words. Write them down once, and every row is checked.

Rules for each column

What it holds (text, number, whole number, date, true or false), required, unique, a range, a list of allowed values, a regular expression.

Suggested from the data

The first thousand rows are read and the rules they already follow are written for you to correct.

Problems in the grid

Cells that break a rule are washed orange; ⌃⌘N walks through them, ⌃⌘K checks again.

JSON Schema, both ways

Write the rules as a JSON Schema to check next month's file anywhere, or turn a data team's schema into this file's rules. What a schema cannot say is named, not dropped.

Dates and decimals, per column

Tell a column whether . or , is its decimal point and how its dates are written — 03/04/2026 is two different days.

A file beside the file

Keep the rules, frozen columns, quoting and sort order in a small .intactmeta file next to the data — the data file itself stays untouched.

Quoting under control

Quote per column, per cell, or only for separators; see which cells will get quotes before you save.

Locked documents

Lock a file and nothing edits it by accident — not typing, not pasting, not a bulk clean-up. A file over five gigabytes opens locked, and says so.

Export and print

38 formats out, with the options each one needs.

Every export can choose its rows, its columns and their order, whether to include the names, how to write empty values and decimal separators — and a file's next export starts where its last one left off.

Columns and their order

Choose which columns go out and in what order; the choice is kept for the file for two years after it was last used, or as long as Settings say.

Spreadsheets

Excel .xlsx with a sheet name and a frozen header, OpenDocument .ods — a million rows in seconds, and an 18-digit code written as text, every digit of it.

Data formats

Parquet, Avro, ORC, Arrow, Feather, BSON, MessagePack, Python pickle, HDF5, SQLite, JSON (flat or nested), JSON Lines, YAML, TOML, GeoJSON, XML.

Statistics packages

SPSS, Stata, SAS transport, R data and MATLAB — with column names and types they understand.

SQL for three databases

CREATE TABLE and inserts for MySQL, PostgreSQL or standard SQL, with types read from the data — DECIMAL for money, CHAR for codes, an enumeration where a column holds a few repeated words.

PDF, ready to send

Paper sizes from A2 to Executive, wide tables kept readable across pages, repeated headings and key columns, page numbers — and PDF/A for archiving, checked with veraPDF.

Word and rich text

A .docx with a formatted table, and rich text that pastes into Pages, Word or Mail as a real table.

Web pages that sort themselves

An HTML table, optionally with a small script to sort, filter and search it in any browser.

Numbered or added to

When the file is already there: replace it, keep it and number the new one, or add the rows to its end.

Your file, your colours

Headers plain, bold or on a band of the colour you choose — and nothing an export writes carries this app's name or colour.

Saved export formats

Any combination of export options saved by name — eleven come built in, including Excel (European), Excel (US) and RFC 4180.

Printing

Printed the way the PDF export sets a table: repeated headings, page numbers, fitted to the width or broken into bands.

Mainframe files

EBCDIC, copybooks and the records a mainframe writes.

A fixed-length file from a mainframe says nothing about itself. The app works out what it can, shows you what it guessed, and keeps what you settle.

52 EBCDIC code pages

Western and Central Europe, Greek, Cyrillic, the Middle East and Asia — the app's own tables, generated from ICU and checked against it.

Read with a copybook

Zoned, packed (COMP-3) and binary numbers, groups, REDEFINES and OCCURS … DEPENDING ON — checked to the byte against AWS's Mainframe Data Utilities.

The copybooks you use, kept

Every copybook that has read a file is kept, and offered for the next file with records of the same length.

A layout written down

A file opened without a copybook is cut where its padding falls; Save the Layout as a Copybook writes that out as COBOL to correct by hand.

Record length by eye

Every length that could be it, likeliest first, with three records one under another — at the right one the fields stand in columns.

Blocked records

A variable-length file still carrying its block descriptors (RECFM=VB) is cut into its records.

Out as well as in

A table exported as mainframe records and the copybook that describes them — numbers as digits, COMP-3 or COMP.

Banking files

Swiss ESR V11 and NACHA ACH records read into their fields, checked against the formats' own arithmetic.

Large files

Millions of rows, and a window that stays smooth.

Files open straight away and stream in behind the window. Nothing that needs the whole table runs against a half-read one — so a file is never saved truncated.

First rows at once

A 325 MB file of 5.2 million rows is on screen in well under a second, and fully read about eight seconds later.

Compact in memory

Values are held as UTF-8 bytes: five million rows take 186 MB instead of 816 MB.

Work while it loads

Scroll, edit and search while the rest arrives; the line at the bottom counts the rows read against the rows expected, and saving, sorting and SQL wait for the last one.

Every format, window first

JSON, XML, YAML and web pages over five megabytes get their window at once and fill it when the reading is done.

Off the main thread

Filtering, searching, column statistics and sorting run to one side, so the window keeps drawing.

Undo that fits in memory

A very large table keeps as many undo steps as fit in half a gigabyte, so sorting a gigabyte file over and over cannot fill your Mac's memory.

Safety

Your file comes first.

An editor of other people's data must never lose it. Every save keeps the version before it; every edit is journalled until it is saved.

A copy before every save

What was on disk is kept aside for 30 days, with a preview for each version and a one-step restore.

Recovery after a crash

Unsaved work is offered back after a crash — as a copy, so you can compare before you decide.

Watching the file

If another program writes to an open file, a bar offers Reload or Keep Mine; unsaved edits are never thrown away unasked.

Undo for everything

Sorts, macros, replacements and pasted blocks, fifty steps by default.

Nothing lost in translation

A character the file's encoding cannot hold stops the save and is named — it is never written as a question mark.

Workbooks go back as themselves

⌘S over an .xlsx keeps its other sheets, column widths, merged cells, names, charts and number formats; only the rows of the sheet you edited are replaced.

Never written back with less

A web page keeps its page, a JSON file its wrapper and comments, a Markdown document its text. A file the app cannot write back whole — a database of several tables — is saved to a copy, and the window says so when it opens.

Damaged files, refused politely

Every reader is tested against files broken on purpose: a damaged file gets a reason, never a crash or a window that stops answering.

Save as you go

Optionally write the file as soon as an edit settles, for people who would rather have no unsaved state at all.

A Mac app

Made for the Mac, and nothing else.

Native Swift and AppKit: fast to start, light and dark, tabs, keyboard everywhere, and the settings you would expect in the places you would look.

Eight languages

English, German, French, Italian, Spanish, Portuguese, Dutch and Polish.

Tabs for every file

Every document opens as a tab of one window; a middle click closes one, as in a browser.

Every format from the Finder

Double-click a Stata file, a pickle or a NetCDF file and it opens here, with a document icon of its own. The app offers itself in Open With without taking a format from another app.

Colours for finding your place

Four grid themes — the system's own, Solarized Light and Dark, Dracula — checked for contrast; a colour for every column; up to three columns marked wherever they are.

Read out loud

Every button that is only a picture has a name for VoiceOver, and the grid tells a screen reader which cell it is in.

Searchable settings

Type into the settings window and every matching setting is listed, under the words people actually use.

Settings as a file

Write every setting and changed shortcut to one readable JSON file, and carry it to another Mac.

Quick to start

About a quarter of a second to a start page, around 100 MB of memory.

Private

No account needed, files never uploaded, updates checked only if you switch it on. Details.

In the app

See it in one window.

Open your most difficult file.

Join the beta and we will write to you as soon as your access is ready. Your files never leave your Mac.

macOS 14 Sonoma or later · How we use your address