tsvkit.org
TSV Toolkit
Sample data Say hi →

Add Row Numbers to a TSV

custom start and step · zero padding · first or last column

Add a counter column so rows have a stable identity. That matters more than it sounds: as soon as you sort, filter, or join a file, the original order is gone and there's no way to get back to it — unless the order was recorded as data first. A row number is also the cheapest surrogate key for a file that has none, and the easiest way to refer to a specific record in a conversation.

number
Drop a .tsv file here, or
ready

How to use

  1. Paste or drop the file. The header row gets the column name, not a number.
  2. Set the start0 for a zero-based index, or a higher number to continue from a previous batch.
  3. Zero-pad if the numbers will be sorted as text somewhere: 007 sorts correctly next to 042 where 7 and 42 do not.
  4. Copy or download.

Two things worth knowing

Number before you sort, not after. Numbering an already-sorted file records the sorted order, which is rarely the one you want to preserve. Add the numbers to the raw export first, then do everything else — you can always sort back with sort on the number column, treated numerically.

Zero padding turns numbers into text. That's the point when the destination sorts lexicographically, but it also means anything reading the column will see a string, and 007 may lose its zeros again on the way through a spreadsheet. Pick padding for filenames and labels, leave it off for anything that goes into a database.

The step field exists for a narrow but real case: numbering in tens or hundreds leaves room to insert rows later without renumbering, the way BASIC line numbers worked. Continuing a sequence across split files is the other — set the start to where the previous part ended.

FAQ

Can it number within groups — restarting per category?

Not directly. Split by column value to get one file per group, number each, then merge them back. That gives you a per-group sequence.

Do the numbers match the file's line numbers?

Not exactly — record 1 is on line 2 of the file because of the header, and a field containing a quoted newline makes a record span several lines. The numbers here count records, which is what error messages from most parsers also count.

What's the shell equivalent?

awk -F'\t' -v OFS='\t' 'NR==1{print "row",$0; next} {print NR-1, $0}' f.tsv, or nl -ba if you don't mind the header being numbered.

Privacy

100% client-side. No upload. See the privacy policy.