行番号の付番方式を変更するnlコマンドのb,f,hオプション

nlコマンドはbオプションやf,hオプションを指定することで、論理ページのセクションごとに付番方式を変更することができます。論理ページについては[前の記事](https://qiita.com/Carol_815/items/d1f52df36b0d39b374b0)をご覧ください。

# b,f,hオプションの使い方

`ｰb`が「ボディ」、`-f`が「フッター」、`-h`が「ヘッダー」をそれぞれ制御しますが、これら3つのオプションの使い方は同じです。付番方式は次の4つの中から指定できます。

| オプション | 付番方式  |
|---|---|
|`a`|すべての行に番号を振る|
|`t`|空行以外に番号を振る|
|`n`|行番号を振らない|
|`p`|正規表現にマッチする行に番号を振る|

オプションは`-b a`というように組み合わせて指定します。なお、4つ目の正規表現についてはこの記事では触れません。

`nl`がデフォルトで空行に番号を振らないことは[前の記事](https://qiita.com/Carol_815/items/0e7de6dd1fb3d821ec6e)でも触れましたが、各セクションごとのデフォルトは、ボディが`t`「空行以外に番号を振る」、ヘッダーとフッターが`n`「行番号を振らない」になっています。`a`を指定することで、他のコマンドのようにすべての行に番号を振るよう変更できます。また、`nl`に行番号を振らない付番方式の指定があるのは少し不思議な感じがしますが、これは一部の行を付番から除外するために必要な方式ということです。

マニュアルも確認していきましょう。

## info nl (GNU coreutils)

```console
‘-b STYLE’
‘--body-numbering=STYLE’
     Select the numbering style for lines in the body section of each
     logical page.  When a line is not numbered, the current line number
     is not incremented, but the line number separator character is
     still prepended to the line. The styles are:

     ‘a’
          number all lines,
     ‘t’
          number only nonempty lines (default for body),
     ‘n’
          do not number lines (default for header and footer),
     ‘pBRE’
          number only lines that contain a match for the basic regular
          expression BRE.  *Note Regular Expressions: (grep)Regular
          Expressions.

‘-f STYLE’
‘--footer-numbering=STYLE’
     Analogous to ‘--body-numbering’.

‘-h STYLE’
‘--header-numbering=STYLE’
     Analogous to ‘--body-numbering’.
```

coreutilsの`nl`では付番方式を「スタイル」と呼んでいます。

## man nl (BSD)

```console
     -b type      Specify the logical page body lines to be numbered.  Recognized
                  type arguments are:

                  a       Number all lines.

                  t       Number only non-empty lines.

                  n       No line numbering.

                  pexpr   Number only those lines that contain the basic regular
                          expression specified by expr.

                  The default type for logical page body lines is t.

     -f type      Specify the same as -b type except for logical page footer
                  lines.  The default type for logical page footer lines is n.

     -h type      Specify the same as -b type except for logical page header
                  lines.  The default type for logical page header lines is n.
```
一方、BSD系の`nl`では付番方式を「タイプ」と呼んでいます。

## busybox nl --help

```console:
	-b STYLE	Which lines to number - a: all, t: nonempty, n: none
```
論理ページをサポートしないbusyboxの`nl`ですが、`-b`だけが存在します。つまり、データを単一のボディとみなして付番方式を変更することができます。そして方式は正規表現を除く3つです。

## POSIX

>-b  type
  Specify which logical page body lines shall be numbered. Recognized types and their meaning are:
a
  Number all lines.
t
  Number only non-empty lines.
n
  No line numbering.
pstring
  Number only lines that contain the basic regular expression specified in string.
  The default type for logical page body shall be t (text lines numbered).

>-f  type
Specify the same as b type except for footer. The default for logical page footer shall be n (no lines numbered).
-h  type
Specify the same as b type except for header. The default type for logical page header shall be n (no lines numbered).

どちらが正しいということはないですが、POSIXでは付番方式を「タイプ」と呼ぶようです。

# bオプションを試す

まずはボディのセクションに対して付番方式をそれぞれ試してみます。

```console
$ echo -e 'a\n\nb' 
a

b
$ echo -e 'a\n\nb' | nl -b a
     1	a
     2	
     3	b
$ echo -e 'a\n\nb' | nl -b t
     1	a
      	
     2	b
$ echo -e 'a\n\nb' | nl -b n
      	a
      	
      	b
```

# f,hオプションを試す

各セクションをまとめて試してみます。

```console:coreutils
$ echo -e '\:\na\n\:\:\nb\n\:\:\:\nc' 
\:
a
\:\:
b
\:\:\:
c
$ echo -e '\:\na\n\:\:\nb\n\:\:\:\nc' | nl -b a -f a -h a

     1	a

     1	b

     1	c
$ echo -e '\:\na\n\:\:\nb\n\:\:\:\nc' | nl -b n -f n -h n

       a

       b

       c
```

```console:BSD
$ echo -e '\:\na\n\:\:\nb\n\:\:\:\nc' | nl -b a -f a -h a
     1	a
     1	b
     1	c
$ echo -e '\:\na\n\:\:\nb\n\:\:\:\nc' | nl -b n -f n -h n
      	a
      	b
      	c
```

coreutilsとBSD系で若干の差異がありますが、空行に付加されるデータ（[前の記事](https://qiita.com/Carol_815/items/0e7de6dd1fb3d821ec6e#%E7%A9%BA%E8%A1%8C%E3%81%AB%E4%BB%98%E5%8A%A0%E3%81%95%E3%82%8C%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF)）の違いと、セクションの区切り文字列を空行に変換する（[前の記事](https://qiita.com/Carol_815/items/d1f52df36b0d39b374b0#%E8%AB%96%E7%90%86%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9)）かどうかの違いだけです。

---