70

My file,

PSS-A  (Primary A)
PSS-B  (Primary B)
PSS-C  (Primary C)
PSS-D  (Primary D)
PSS-E  (Primary E)
PSS-F  (Primary F)
PSS-G  (Primary G)
PSS-H  (Primary H)
PSS-I  (Primary I)
SPARE  (SPARE)

Output file,

 1> PSS-A  (Primary A)
 2> PSS-B  (Primary B)
 3> PSS-C  (Primary C)
 4> PSS-D  (Primary D)
 5> PSS-E  (Primary E)
 6> PSS-F  (Primary F)
 7> PSS-G  (Primary G)
 8> PSS-H  (Primary H)
 9> PSS-I  (Primary I)
10> SPARE  (SPARE)
jimmij
  • 46,064
  • 19
  • 123
  • 136
Nainita
  • 2,712
  • 12
  • 33
  • 50

4 Answers4

104

The right tool for this job is nl:

nl -w2 -s'> ' file

You may want to tune width option according to the total number of lines in the file (if you want numbers to be aligned nicely).

Output:

 1> PSS-A  (Primary A)
 2> PSS-B  (Primary B)
 3> PSS-C  (Primary C)
 4> PSS-D  (Primary D)
 5> PSS-E  (Primary E)
 6> PSS-F  (Primary F)
 7> PSS-G  (Primary G)
 8> PSS-H  (Primary H)
 9> PSS-I  (Primary I)
10> SPARE  (SPARE)
jimmij
  • 46,064
  • 19
  • 123
  • 136
  • 7
    `nl` treats lines that contain a sequence of 1, 2 or 3 `\:` strings specially. Use `-d $'\n'` to avoid that. Also, by default, it doesn't number empty lines. Use `-ba` to number every line. – Stéphane Chazelas Jan 30 '18 at 15:57
  • @StéphaneChazelas indeed, thanks a lot! Note that `$'...'` syntax is bash-specific. – myrdd Nov 06 '18 at 16:17
  • My heart sank when I saw that `seq` didn't do it. Thank god for `nl` – Sridhar Sarnobat Jan 09 '19 at 17:56
  • 2
    @myrdd, `$'...'` comes from ksh93 and is also supported by `zsh`, `mksh`, busybox sh, FreeBSD sh and bash at least. It's not standard yet, but is planned for inclusion in the next major POSIX version. – Stéphane Chazelas Feb 19 '19 at 10:08
  • @StéphaneChazelas thanks. for reference, there's a question on `$'...'` (ANSI-C Quoting) portability: https://unix.stackexchange.com/questions/371827/do-shells-other-than-bash-and-zsh-support-ansi-c-quoting-e-g-string – myrdd Feb 19 '19 at 16:20
  • I like how `nl` can set a starting number with `-v`. – Onnonymous Jun 12 '19 at 07:00
64

If you want the same format that you have specified

awk '{print NR  "> " $s}' inputfile > outputfile

otherwise, though not standard, most implementations of the cat command can print line numbers for you (numbers padded to width 6 and followed by TAB in at least the GNU, busybox, Solaris and FreeBSD implementations).

cat -n inputfile > outputfile

Or you can use grep -n (numbers followed by :) with a regexp like ^ that matches any line:

grep -n '^' inputfile > outputfile
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
amisax
  • 2,957
  • 17
  • 23
  • Yes...both the commands are working.... but in `cat` command its printing the line numbers... but not exactly what I wanted.... but `awk '{print NR "> " $s}' inputfile > outputfile` gives me the desired output.... :-) @amit kumar – Nainita Aug 10 '15 at 15:29
  • 2
    Note also that `cat -n` is not portable. Only the `-u` option is specified in [POSIX `cat`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cat.html). – vinc17 Oct 08 '18 at 10:43
3

In Linux/Unix, there are almost always multiple ways to do common tasks. Just for completeness, here are some other ways you can do it besides the obvious:

    pr -t -n [file]

From an old command to format text to send to a line printer. The '-t' will omit header and footer information that are not relevant to a terminal.

Here's a cute sed method that prints the line number on every other line. We use 'paste' to fold them into a single line:

    sed = /etc/passwd | paste - -

Or, we can use the one true editor, ed:

    echo '1,$n' | ed -s [file]

Or, ex, vi's non-cursor-addressing predecessor:

    printf 'set number\ng/^/p\n' | ex /etc/passwd

And one final complicated answer, requiring ksh93 or bash (and the seq command. Using the .. range and an eval statement is left as an exercise):

    paste <(seq $(wc -l < [file])) [file]

Tested on Debian Linux, FreeBSD, and Solaris 10 (the last fails there because of no 'seq').

0

i have done by below method

command: cat -n filename |sed -r "s/^\s+//g"| sed "s/^[0-9]*/&\> /g"

output

cat -n u.txt |sed -r "s/^\s+//g"| sed "s/^[0-9]*/&\> /g"
1>  PSS-A  (Primary A)
2>  PSS-B  (Primary B)
3>  PSS-C  (Primary C)
4>  PSS-D  (Primary D)
5>  PSS-E  (Primary E)
6>  PSS-F  (Primary F)
7>  PSS-G  (Primary G)
8>  PSS-H  (Primary H)
9>  PSS-I  (Primary I)
10>     SPARE  (SPARE)
Praveen Kumar BS
  • 5,139
  • 2
  • 9
  • 14
  • please add an explanation, I'd love to do this with sed, but I don't understand the command :) – xeruf Jul 16 '20 at 19:30