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

  • What I'm wondering is how you'd do it on Windows...
    – itsadok
    Jul 21 '09 at 17:37
  • 4
    Should this be on stackoverflow? For superuser the answer is Notepad & lots of patience.
    – kokos
    Jul 21 '09 at 22:10
  • 2
    So, do you want to prepend or append. Your title and body texts are different ;)
    – matpie
    Jul 22 '09 at 23:52
  • I guess I want to append to the beginning, "prepend" being only a word to hackers. Jul 23 '09 at 0:15
  • On Windows, as with any other programming-ish question, you could install Cygwin and then use the answers below. Aug 10 '13 at 14:45
awk '{printf "%d\t%s\n", NR, $0}' < filename
  • 13
    Or awk '{print NR, "\t", $0}'.
    – jtbandes
    Jul 23 '09 at 1:18
  • 2
    answer below, with nl command line, is a much simpler solution. Oct 8 '12 at 20:38
  • 2
    @DanielRibeiro simpler but less reliable and less flexible. Aug 10 '13 at 15:01
  • @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
    Apr 23 '18 at 14:04
  • @jtbandes Your solution adds spaces between the line number and tab (at least on my mac) Jun 18 '19 at 6:53

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$.
  • 5
    Actually, 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
    Feb 26 '13 at 23:09
  • 2
    Beware 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. Aug 10 '13 at 14:49
  • 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. Aug 10 '13 at 14:58
  • 4
    With -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). Dec 18 '14 at 23:17
  • 2
    @JonathanHartley nl -w1 (from GNU coreutils 8.24) does not truncate the line numbers. Jan 8 '18 at 14:57
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.

  • 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, Jul 21 '09 at 16:49
  • 1
    Note 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). Aug 3 '14 at 6:19
  • (Yay nitpicking!) Aug 3 '14 at 6:19
  • If we're going to get into nitpicking about how windows might be different, then we might need to consider UTF16.
    – mc0e
    Jan 21 '17 at 12:50
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"

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


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

How about

cat -n somefile.txt


  • 1
    No tab. (Comments needing 15 chars is a stupid requirement.) Jul 21 '09 at 16:42
  • 1
    This produces tabs on my system. cat (GNU coreutils) 6.10.
    – innaM
    Jul 21 '09 at 16:50
  • On my system, it adds (tab)number(space)line. BSD Utils. Jul 21 '09 at 16:59

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!


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  =====>  ---- 
  • Now I see this. OK, delete my own post. What? You say that SU doesn't let you delete your own post?
    – Kevin M
    Jul 23 '09 at 0:42
  • grep + sed == awk Jul 23 '09 at 12:50
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//'
  • Prints a "t" with no tab with my version of sed. Jul 21 '09 at 16:54
  • Edited to double-escape; try it like that.
    – chaos
    Jul 21 '09 at 17:18
  • If all else fails, just hit tab. :) (Or ^V tab if your shell gives you trouble with that.)
    – chaos
    Jul 21 '09 at 17:19
  • sed: 1: "test.txt": undefined label 'est.txt' Jul 21 '09 at 17:24
  • 'cat test.txt | sed -e 's/^/\\t/' | cat -n' prints (tab)number(space)\t(line) Jul 21 '09 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.