How can I prepend a line number and tab to each line of a text file?

45

10

How can I append a line number and tab to the beginning of each line of a text file?

Richard Hoskins

Posted 2009-07-21T16:30:41.993

Reputation: 10 260

On Windows, as with any other programming-ish question, you could install Cygwin and then use the answers below. – Jonathan Hartley – 2013-08-10T14:45:06.333

What I'm wondering is how you'd do it on Windows... – itsadok – 2009-07-21T17:37:12.820

4Should this be on stackoverflow? For superuser the answer is Notepad & lots of patience. – kokos – 2009-07-21T22:10:14.487

2So, do you want to prepend or append. Your title and body texts are different ;) – matpie – 2009-07-22T23:52:44.250

I guess I want to append to the beginning, "prepend" being only a word to hackers. – Richard Hoskins – 2009-07-23T00:15:58.640

Answers

49

awk '{printf "%d\t%s\n", NR, $0}' < filename

pgs

Posted 2009-07-21T16:30:41.993

Reputation: 3 153

@DanielRibeiro The answer using nl is also WRONG. In source code, it will never give you the right line numbers, as it doesn't count lines with only whitespace. – oligofren – 2018-04-23T14:04:44.313

@jtbandes Your solution adds spaces between the line number and tab (at least on my mac) – Yossi Vainshtein – 2019-06-18T06:53:45.783

1answer below, with nl command line, is a much simpler solution. – Daniel Ribeiro – 2012-10-08T20:38:48.013

2@DanielRibeiro simpler but less reliable and less flexible. – Jonathan Hartley – 2013-08-10T15:01:49.903

10Or awk '{print NR, "\t", $0}'. – jtbandes – 2009-07-23T01:18:41.963

55

The nl command should do this, but it adds space before the line number too. It's part of Linux coreutils.

nl lines.txt
 1  $bkWTN
 2  $cV8$.

ACoolie

Posted 2009-07-21T16:30:41.993

Reputation: 761

4With -nln you can left-justify if you don't want the space(s) before line numbers. Also, to specify a tab separator you could use -s$'\t' or -s' ' (insert a tab between the single quotes with ctrl+v then tab). – don_crissti – 2014-12-18T23:17:36.420

2@JonathanHartley nl -w1 (from GNU coreutils 8.24) does not truncate the line numbers. – Skippy le Grand Gourou – 2018-01-08T14:57:25.290

This is wrong. It skips/doesn't count lines composed of line numbers. The accepted answer works. – oligofren – 2018-04-23T14:03:49.120

4Actually, you can tell nl to omit the space before the number. Just use the -w1 option to tell it the minimum width for a number is 1. – cjm – 2013-02-26T23:09:18.223

2Beware that 'nl' assumes by default that your text is split into 'pages' with headers and footers, all delimited by lines like ':' or '::' or ':::'. If your text has any lines like this in it, then 'nl' will produce unexpected results, such as swallowing those lines, sections with no numbering, or restarting the numbering from 1 in a section. Use -dXY (where XY is a pair of characters that do not occur on a line by themselves in your text) to prevent this behaviour. In the general case, this might be hard to predict, so I'd recommend using one of the other solutions on this page. – Jonathan Hartley – 2013-08-10T14:49:42.697

Using '-w1' will not just remove the space after the numbers, but will also truncate the line numbers to only be one character wide, meaning your lines numbers only display their least significant digit. This is almost certainly not what you want. – Jonathan Hartley – 2013-08-10T14:58:57.267

10

sed = test.txt | sed 'N;s/\n/\t/'

The command "sed =" will print the line number followed by a carriage return and then the next line.

The expression "N;s/\n/\t/" will take each line, get the next line (ie line number and the line), and replace the carriage return with a tab.

Callum

Posted 2009-07-21T16:30:41.993

Reputation: 1 526

1Note that \n is line feed (commonly called just "newline", since its first widespread usage was in Unix), and \r is carriage return. Windows uses \r\n (also referred to as CRLF). – Camilo Martin – 2014-08-03T06:19:34.240

(Yay nitpicking!) – Camilo Martin – 2014-08-03T06:19:52.520

If we're going to get into nitpicking about how windows might be different, then we might need to consider UTF16. – mc0e – 2017-01-21T12:50:12.553

Prints a "t" with no tab with my version of sed:

8t I saw the best minds of my generation destroyed by 9t madness, starving hysterical naked, – Richard Hoskins – 2009-07-21T16:49:43.883

4

cat -n <yourfile> | perl -pe "s/^\s*(\d+)\s+/\1\t/"

cat -n adds linenumbers as " 123 linecontents" and that regexp modifies it to "linenumberTABlinecontents"

raspi

Posted 2009-07-21T16:30:41.993

Reputation: 911

3

perl -pe "s/^/$.\t$_/" file.txt

or

perl -ne "print qq($.\t$_)" file.txt

itsadok

Posted 2009-07-21T16:30:41.993

Reputation: 1 560

2

How about

cat -n somefile.txt

?

innaM

Posted 2009-07-21T16:30:41.993

Reputation: 9 208

1No tab. (Comments needing 15 chars is a stupid requirement.) – Richard Hoskins – 2009-07-21T16:42:46.333

1This produces tabs on my system. cat (GNU coreutils) 6.10. – innaM – 2009-07-21T16:50:41.073

On my system, it adds (tab)number(space)line. BSD Utils. – Richard Hoskins – 2009-07-21T16:59:20.647

2

OK, Here's a one-line bash solution:

$ IFS=$'\n';x=1;for l in $(<file.txt);do echo -e "$x\t$l";((x+=1));done
$ IFS=

The first IFS setting tells bash to read a full line at a time. The second line resets the IFS to default.

As an added bonus, it runs completely in your shell and doesn't exec a program!

P. Heffner

Posted 2009-07-21T16:30:41.993

Reputation: 184

1

sed file.txt -e 's/^/\t/' | cat -n | sed -e 's/^\t//'

or for some non-GNU seds:

cat file.txt | sed -e 's/^/\\t/' | cat -n | sed -e 's/^\\t//'

chaos

Posted 2009-07-21T16:30:41.993

Reputation: 1 599

Prints a "t" with no tab with my version of sed. – Richard Hoskins – 2009-07-21T16:54:05.090

Edited to double-escape; try it like that. – chaos – 2009-07-21T17:18:15.500

If all else fails, just hit tab. :) (Or ^V tab if your shell gives you trouble with that.) – chaos – 2009-07-21T17:19:49.273

sed: 1: "test.txt": undefined label 'est.txt' – Richard Hoskins – 2009-07-21T17:24:20.477

'cat test.txt | sed -e 's/^/\t/' | cat -n' prints (tab)number(space)\t(line) – Richard Hoskins – 2009-07-21T17:25:36.467

Okay, two versions, second one for your sed, both getting rid of the leading tab cat -n likes. – chaos – 2009-07-21T18:09:30.493

Just an aside, my sed isn't old. It's just not GNU. :) – Richard Hoskins – 2009-07-22T21:41:03.770

Duly noted, edited per. :) – chaos – 2009-07-22T22:18:00.730

1

Ok, since we are collecting ways to do this,

 grep -n . file.txt | sed 's/\(^[0-9]*\):/\1    /g'
 # this is a tab with Ctrl-V + Tab  =====>  ---- 

nik

Posted 2009-07-21T16:30:41.993

Reputation: 50 788

Now I see this. OK, delete my own post. What? You say that SU doesn't let you delete your own post? – Kevin M – 2009-07-23T00:42:53.260

grep + sed == awk – Tadeusz A. Kadłubowski – 2009-07-23T12:50:49.880