CSV Null Standardizer
Turn every flavour of "no data" — NA, N/A, NULL, NaN, a bare dash, an empty cell — into the one token you actually want, without touching your real values.
About this tool
Open enough real CSV exports and you will find the same column expressing "no data" four different ways: an empty cell here, NA there, #N/A from a spreadsheet, null from a database dump, and a lone - typed by whoever maintained the sheet by hand. Every downstream step then needs its own list of exceptions — a na_values= argument, a CASE WHEN in the load script, a find-and-replace before the import.
This tool collapses all of that into one rule. Paste the table, pick the single representation you want, and every cell that means "missing" is rewritten to it. Everything else is left exactly as it was: real values are copied byte-for-byte (padding included), the header row is never touched, quoted fields keep their quoting, ragged rows keep their length, and the field separator round-trips unchanged.
It standardizes the token, not the data. Nothing is guessed, averaged, or filled in — if you need means, medians, or nearest-neighbour fills, that is imputation and a different job. If you first want to know how much is missing and where, profile the table before you normalize it.
Worked example
Input (delimiter comma, replace with NULL, defaults everywhere else):
id,score,notes
1,42,ok
2,NA,
3,null,-
4,n/a,NaN
Output:
id,score,notes
1,42,ok
2,NULL,NULL
3,NULL,NULL
4,NULL,NULL
Note what did not change: the header stays id,score,notes even though a header cell could match a token, and 42/ok are untouched. n/a matched N/A because matching is case-insensitive by default, and the empty cell on row 2 matched because blank cells count as missing.
Controls
- Delimiter —
comma(default),tab,semicolon,pipe, any single character, orautoto sniff the separator from the first line. The output always uses the same separator as the input. - Tokens that count as missing — the comma-separated vocabulary, pre-filled with
NA,N/A,N.A.,#N/A,#N/A N/A,#NA,NULL,NIL,NaN,None,<NA>,-,--, and?. Edit it in place: add a project sentinel like-999, or delete entries you use as real values. Clear it entirely to standardize only blank cells. - Replace missing cells with — the one representation you want. Leave it blank for an empty cell; type
NULL,NA,NaN, or\N(the sentinel a PostgresCOPY … WITH (FORMAT csv, NULL '\N')load expects). - Also standardize blank / whitespace-only cells — on by default. Turn it off to convert the listed tokens and leave already-empty cells empty.
- Match tokens case-sensitively — off by default, so a single
NULLentry also catchesnullandNull. Turn it on when case carries meaning. - Ignore whitespace around a cell when matching — on by default, so
NAis recognised. This only affects matching; a cell that is not missing keeps its padding. - First row is a header — on by default. The header is copied through untouched and supplies the names used by the column filter.
- Only these columns — comma-separated column names (needs a header) or 1-based positions, e.g.
score,notesor2,4. Blank means every column, and you never have to split the file up to normalize one field. - Output quoting —
minimalquotes only fields that require it,alwaysquotes every field including the replacement token,neverwrites bare fields. Keepminimalwhen your replacement is a loader sentinel like\N, because a quoted"\N"is read as the literal two-character string.
Limits and edge cases
The table is capped at 5,000,000 bytes. A row shorter than the header stays short — missing trailing cells are not invented, because writing a value into a column the row never had would change its shape. Because the token list itself is comma-separated, a token that literally contains a comma cannot be expressed. Choosing never for output quoting can produce ambiguous CSV when a value contains the separator or a newline, so keep minimal unless a downstream reader demands otherwise. Output rows are terminated with a single newline (\n), and the result always ends with one. Everything runs locally in your browser — the table is never uploaded.
FAQ
Which tokens count as missing by default?
NA, N/A, N.A., #N/A, #N/A N/A, #NA, NULL, NIL, NaN, None, <NA>, -, --, and ? — plus any cell that is empty or whitespace-only. Matching ignores case and surrounding whitespace by default, so one NULL entry covers null, Null, and NULL. The list is an editable field, not a fixed rule: add your own sentinels or delete the ones that are real values in your data.
A real value in my data is a dash — how do I protect it?
Two ways. Delete - from the Tokens that count as missing list so a dash is never treated as missing anywhere, or leave the list alone and use Only these columns to restrict the rewrite to the columns where a dash really does mean "no data". The header row is protected either way, so a column named - or NA always survives.
How do I produce a file a Postgres COPY can load?
Set Replace missing cells with to \N and load with COPY table FROM 'file.csv' WITH (FORMAT csv, HEADER, NULL '\N'), and leave Output quoting on minimal — Postgres only honours the NULL sentinel when it is unquoted.
If you were hoping to keep an empty string distinct from a NULL, that distinction cannot survive this tool: a bare empty cell and a quoted "" both read as the same empty value on the way in, so there is nothing left to tell apart on the way out. Use a sentinel like \N for the missing cells instead, and anything that is still blank is your empty string.
Will this fill in the missing values for me?
No, and that is deliberate. This tool only makes the representation consistent; it never invents data. Substituting a mean, median, most-frequent value, or a nearest-neighbour estimate is imputation, which changes your dataset's statistics and belongs in a dedicated imputation step you can review separately.
Does it handle TSV, semicolon, and pipe files?
Yes. Choose tab, semicolon, or pipe by name, type any single character, or pick auto to detect the separator from the first line (it counts candidates outside quoted fields and prefers a comma on a tie). Whatever separator comes in is what goes back out, so the file shape is preserved.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool csv-null-standardizer "id,score,notes
1,42,ok
2,NA,
3,null,-
4,n/a,NaN"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/csv-null-standardizer/?input=id%2Cscore%2Cnotes%0A1%2C42%2Cok%0A2%2CNA%2C%0A3%2Cnull%2C-%0A4%2Cn%2Fa%2CNaN&delimiter=comma&na_tokens=NA%2CN%2FA%2CN.A.%2C%23N%2FA%2C%23N%2FA%20N%2FA%2C%23NA%2CNULL%2CNIL%2CNaN%2CNone%2C%3CNA%3E%2C-%2C--%2C%3F&replace_with=NULL&blank_is_missing=true&case_sensitive=true&trim=true&header=true&columns=score%2Cnotes"e_style=minimalMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
