59

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

5
  • What I'm wondering is how you'd do it on Windows...
    – itsadok
    Jul 21, 2009 at 17:37
  • 4
    Should this be on stackoverflow? For superuser the answer is Notepad & lots of patience.
    – kokos
    Jul 21, 2009 at 22:10
  • 2
    So, do you want to prepend or append. Your title and body texts are different ;)
    – matpie
    Jul 22, 2009 at 23:52
  • I guess I want to append to the beginning, "prepend" being only a word to hackers. Jul 23, 2009 at 0:15
  • On Windows, as with any other programming-ish question, you could install Cygwin and then use the answers below. Aug 10, 2013 at 14:45

9 Answers 9

61
awk '{printf "%d\t%s\n", NR, $0}' < filename
5
  • 14
    Or awk '{print NR, "\t", $0}'.
    – jtbandes
    Jul 23, 2009 at 1:18
  • 2
    answer below, with nl command line, is a much simpler solution. Oct 8, 2012 at 20:38
  • 2
    @DanielRibeiro simpler but less reliable and less flexible. Aug 10, 2013 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, 2018 at 14:04
  • @jtbandes Your solution adds spaces between the line number and tab (at least on my mac) Jun 18, 2019 at 6:53
63

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$.
6
  • 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, 2013 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, 2013 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, 2013 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, 2014 at 23:17
  • 3
    @JonathanHartley nl -w1 (from GNU coreutils 8.24) does not truncate the line numbers. Jan 8, 2018 at 14:57
10
sed = test.txt | sed 'N;s/\n/\t/'

The sed = command 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 (i.e. line number and the line), and replace the carriage return with a tab.

4
  • 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, 2009 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, 2014 at 6:19
  • (Yay nitpicking!) Aug 3, 2014 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, 2017 at 12:50
5
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"

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

or

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

How about

cat -n somefile.txt

?

3
  • 1
    No tab. (Comments needing 15 chars is a stupid requirement.) Jul 21, 2009 at 16:42
  • 1
    This produces tabs on my system. cat (GNU coreutils) 6.10.
    – innaM
    Jul 21, 2009 at 16:50
  • On my system, it adds (tab)number(space)line. BSD Utils. Jul 21, 2009 at 16:59
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!

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .