The manpage for nl(1) reads:

  The nl utility treats the text it reads in terms of logical
  pages.  Unless specified otherwise, line numbering is reset at the
  start of each logical page.  A logical page consists of a header, a
  body and a footer section; empty sections are valid. [...]

POSIX.1-2017 basically says the same thing:

  The nl utility views the text it reads in terms of logical pages. Line
  numbering shall be reset at the start of each logical page. A logical
  page consists of a header, a body, and a footer section. Empty
  sections are valid. 

However, nl(1)'s behavior doesn't fit that description.  Numbering is
actually reset at the start of each page section, not the start of the
page.

A practical example will demonstrate the difference.  Here's a simple
input file:

\:\:\:
Header 1
\:\:
Body 1
Body 1
\:
Footer 1
\:\:\:
Header 2
\:\:
Body 2
Body 2
Body 2
\:
Footer 2

If we tell nl(1) to number all the the lines in all sections, we get
this:

$ nl -ba -fa -ha file
     1  Header 1
     1  Body 1
     2  Body 1
     1  Footer 1
     1  Header 2
     1  Body 2
     2  Body 2
     3  Body 2
     1  Footer 2

Which doesn't look right.  The numbering restarts every time we
cross a section boundary.

With the attached patch we get this:

$ nl -ba -fa -ha file
     1  Header 1
     2  Body 1
     3  Body 1
     4  Footer 1
     1  Header 2
     2  Body 2
     3  Body 2
     4  Body 2
     5  Footer 2

Now the numbering restarts at the start of a header section, i.e. at
the start of the page.

I think this is the behavior we want.

So, with this patch we only restart numbering when we find a header
marker.

Thoughts?  ok?

Index: nl.c
===================================================================
RCS file: /cvs/src/usr.bin/nl/nl.c,v
retrieving revision 1.7
diff -u -p -r1.7 nl.c
--- nl.c        21 Apr 2019 01:08:46 -0000      1.7
+++ nl.c        19 Nov 2021 21:05:22 -0000
@@ -261,7 +261,7 @@ filter(void)
                        if (buffer[delimlen * (idx + 1)] == '\n') {
                                section = idx;
                                adjblank = 0;
-                               if (restart)
+                               if (restart && section == HEADER)
                                        line = startnum;
                                goto nextline;
                        }

Reply via email to