CSV to TSV Converter
Change a CSV's delimiter to tab, semicolon, pipe or anything you type — re-quoted correctly, entirely on this device.
- Minimal quotes a field only when it holds the target delimiter, a double quote, CR or LF — quotes the input no longer needs are dropped.
- Tab target with Minimal quoting only — tab readers ignore quotes, so a cell holding a tab or a line break needs a decision: Quote writes RFC 4180 quotes, Escape writes \t, \r, \n and \\, Refuse writes nothing at all. Escaping is one-way: Swap does not turn \t back into a tab.
- Type a character, or an escape like \t or \u00a6.
- A byte-order mark makes spreadsheet apps read the download as UTF-8.
Press ? for shortcuts
Do it offline:$ csvformat -D $'\t' data.csv
How to use it
- Paste the text or drop the file in — the badge over the left pane names the separator found, and one click pins your own pick instead.
- Pick the target — tab, semicolon, pipe, comma — or type one in the custom field, where escapes such as \t and \u001f are decoded.
- Set quoting, the line ending and the byte-order mark to suit whatever reads the file next; with a tab target, decide how a cell already holding a tab travels.
- Take the result by Copy, by Download (the extension follows the target) or as a link — nothing is sent anywhere.
A file named .csv is frequently not comma-separated. A spreadsheet export from a semicolon locale, a log pipeline that chose the pipe, an import form that insists on tabs: same rows, different separator. Paste it, pick the separator the other side wants, and every field is re-quoted for that separator. What was detected is shown on a badge, and one click overrides it.
How it works
Detection reads the first twenty records inside the leading 256 KB and counts commas, semicolons, tabs and pipes falling outside quoted fields. A candidate scores only when every sampled record holds the same non-zero count of it, and the highest consistent count wins; nothing beyond those four counts, so a caret-separated file is an explicit pick. Two failures get reported rather than resolved: widths that genuinely differ near the top, and a tie.
Reading keeps each field's text and discards which fields had been wrapped, so wrapping is computed again rather than copied. Under minimal quoting a field is wrapped exactly when it holds the target separator, a double quote, a carriage return or a line feed; an inner double quote is written twice; a field no longer needing wrapping loses it. Quote every field skips the test. Reproducing the input's own wrapping is unavailable — the parse forgot it.
Examples
sku,label,region
A-19,Desk lamp,EU
B-04,Floor lamp,APACsku label region
A-19 Desk lamp EU
B-04 Floor lamp APACThe plain case: no field holds a tab, a quote or a break, so nothing is wrapped and every cell arrives character for character.
sku;label;price
A-19;Cable, 2 m;9,90
B-04;Adapter;14,00sku,label,price
A-19,"Cable, 2 m","9,90"
B-04,Adapter,"14,00"Three fields carried a comma — one in a product name, two as a decimal comma — so each is wrapped to survive as one field, listed by row and column.
step,command
build,"make all"step command
build make\tallThe edge case: the cell already holds a tab and the target is the tab. Escape (shown) writes \t, the convention the IANA registration describes; Quote wraps instead; Refuse writes nothing.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Old quotes do not come back
A field quoted only for the previous separator arrives bare, its characters untouched.
Source and target the same is still a run
Comma to comma is allowed and noted — the way to change only quoting, the line ending or the byte-order mark.
Short rows keep their own width
Three cells among four-cell rows leave as three, counted in a warning. Squaring up adds fields nobody wrote.
A separator at the end of a line is a field
Trailing separators mean a real empty last field, written back the same way.
Up to eight characters, taken literally
Sequences such as || and ~|~ work. They match as text, never as a pattern, so a dot is just a dot.
Tab targets cannot rely on quoting
Plenty of tab readers ignore double quotes, so a cell holding a tab needs a decision: wrap, backslash-escape or stop.
A tie is reported, never resolved
Two candidates equally often, or none consistent, drops the badge to low confidence and names the reading.
Line endings and the byte-order mark are yours
Mixed CRLF and LF is noted and leaves as the ending you chose. A leading byte-order mark is dropped, re-added only on request.
Common errors
Row 2: quoted field opened at column 5 never closes — this usually swallows every following row; close the quote, or write a quote inside a field as "".- An opening quote with no partner turns the remainder of the file into one enormous field, so the run stops rather than produce a wrong table. A code frame points at it.
Row 2, column 2: the cell "make all" contains the delimiter or a line break, which this delimiter cannot carry safely — choose Quote or Escape, or pick another delimiter.- Refuse was picked, the target is the tab and a cell holds one. Nothing is written — half a file is worse than none — and the cell is quoted back with its position.
Delimiter contains a double quote — the quote character marks field boundaries, so it cannot also separate fields.- The custom field was given a double quote, which already means “a field starts or ends here”. The same field rejects a bare line break and anything past eight characters.
Input is larger than the 100 MB limit for this tool.- Past the cap the page refuses outright rather than doing part of the file and letting you believe it finished. The banner repeats the command line below.
FAQ
Is TSV just a CSV file with tabs?
Not quite. The IANA registration for text/tab-separated-values describes no quoting mechanism, so many readers take a double quote as an ordinary character. Hence the tab target asking how a cell holding a tab should travel.
How do I go the other way, tab back to comma?
Swap. It moves the result into the left pane, trades the separators and runs again — the same route for semicolon to comma and pipe to comma. Escape it cannot undo: \t stays two characters.
Why does my spreadsheet export use semicolons?
Where the comma is the decimal mark, the list separator is normally the semicolon, and exports follow the regional setting rather than the file extension — Microsoft documents that.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Separate again now — how the largest inputs are run.
- ⌘/Ctrl + S
- Save the result; its extension tracks the target.
- ⌘/Ctrl + C
- Clipboard the whole result while nothing is selected.
- ⌘/Ctrl + Shift + C
- Clipboard the whole result even mid-selection.
- s
- Send the result leftward and trade the separators.
- t
- Hop to whichever palette is not showing.
- ? or ⌘/Ctrl + /
- Show this list inside the tool.
- Esc
- Close whatever is on top.