3

I need to write a program that reads lines from a file on stdin and writes the lines to stdout with line numbers. I cannot use cat -n.

Let's say the text file had this:

 abcdef
 ghi

 klm
 nopqr st

It should basically read those lines and output those lines but with lines numbers.

This is the while read loop I have but it doesn't print out every line.

while read line
do
    awk '{print NR, $0}'

done < file

Basically what this output is this:

1 ghi
2 
3 klm
4 nopqr   st

For some reason the abcdef doesn't show up and number 2 isn't supposed to be blank.

  • 2
    You don't need the loop, Awk can handle this: awk '{print NR, $0}' file... – jasonwryan Feb 27 '16 at 7:08
  • yeah but one line is just blank – shawn edward Feb 27 '16 at 7:15
  • 3
    what's wrong with cat -n? – cas Feb 27 '16 at 7:17
  • forgot to mention the question said dont use "cat -n" – shawn edward Feb 27 '16 at 7:26
  • 1
    Is it homework? – ctrl-alt-delor Feb 27 '16 at 10:39
8

Have you tried nl -b a <file_name>

debian@virt00:~/test$ nl -b a file
     1  abcdef
     2   ghi
     3
     4   klm
     5   nopqr st
debian@virt00:~/test$
  • nl stands for number line
  • -b flag for body numbering
  • 'a' for all lines.

for more information http://linux.die.net/man/1/nl

3
awk '$0!=""{print NR, $0}' file

The $0 != "" means $0 not equal to empty. For those lines print line number and line.


That will produce this output:

1 abcdef
2 ghi
4 klm
5 nopqr st

with the old line numbers. If you need the output with the new line numbers:

awk '$0!=""{a++; print a, $0}' file

1 abcdef
2 ghi
3 klm
4 nopqr st

To explain how your script worked:

The line with read line will read the first line (you do not print it).
Then, you connect the file to awk and it process all the other lines.
Awk does not (by default) obviate empty lines, so the empty line is also printed.

There are many ways to solve this, the one above seems as simple as is possible.

  • Upvoted for explanation of what was wrong with OP's attempt. – John Auld Feb 27 '16 at 21:43
  • fyi, your awk example can be simplified to awk '!!$0{ print ++a,$0; }' – DarkHeart Feb 29 '16 at 2:04
  • @DarkHeart Of course, you are right. Trying to be KISS. :-) ..... Of course, note that this also works: awk '$0{print ++a, $0}' file. – user79743 Feb 29 '16 at 2:15
2

You may use "cat -n", flag "-n" is to add the numbers to the output lines of "cat".

  • Edited the main question, can't use "cat -n" – shawn edward Feb 27 '16 at 7:27
  • Then use '''( let n=0; while read line; do echo "$n $line"; let n++; done )''' – Andrew Miloradovsky Feb 27 '16 at 7:33
  • @shawnedward if the reason not to used cat -n are the empy lines then delete them first sed "/^$/d" | cat -n – humanityANDpeace Feb 27 '16 at 7:47
  • 1
    And also there is "-b" flag for "cat"... – Andrew Miloradovsky Feb 27 '16 at 7:52
  • 1
    and last but not least cat -n | sed -e '/^[ \t0-9]*$/d' would include empty lines in numbering yet not print those lines (which would be a cat --number-all-only-show-nonblank of sorts) – humanityANDpeace Feb 27 '16 at 8:07
-1
#!/bin/bash

awk '!/^$/{print ++a, $0}' file

echo

awk '!!$0{print ++a, $0}' file

echo

awk '{if ($0 != "") print ++aa, $0}' file

echo

NR=0
while read -r
do
    [[ "${REPLY}" = "" ]] || echo $((++NR)) "${REPLY}"
done < file

echo

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.