nlコマンドはwオプションを指定することで、行番号の桁数を変更することができます。
wオプションの使い方
まずはマニュアルを参照してみましょう。
info nl (GNU coreutils)
‘-w NUMBER’
‘--number-width=NUMBER’
Use NUMBER characters for line numbers (default 6).
coreutilsは非常にシンプルに記載されています。桁数を変更するには-w
のあとに数字を指定するだけです。そして-nオプションの記事で調べたとおり、デフォルトの桁数は6桁になります。
busybox nl --help
-w N Width of line numbers
busyboxでも-wオプションは使うことができます。ヘルプはcoreutils以上にシンプルな記述です。
man nl (BSD)
-w width Specify the number of characters to be occupied by the line num-
ber; in case the width is insufficient to hold the line number,
it will be truncated to its width least significant digits. The
default width is 6.
一方でBSDのマニュアルにはcoreutilsに比べて長い説明が書かれています。主な差分は「幅が行番号を保持するのに十分でない場合、行番号は有効な幅の桁数以下に切り捨てられる」ということのようです。これはあとで検証してみましょう。
POSIX
-w width
Specify the number of characters to be used for the line number. The default width shall be 6.
出典:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html
ちなみにPOSIXでは「幅が十分でない場合」について言及は無いようです。この条件において互換性は保証されていません。
wオプションを試す
それでは最初の記事で使用したテキストファイル「utl-kita」で実際に試してみましょう。
$ nl -w 1 utl-kita
1 東京
2 上野
3 尾久
4 赤羽
5 浦和
6 さいたま新都心
7 大宮
$ nl -w 10 utl-kita
1 東京
2 上野
3 尾久
4 赤羽
5 浦和
6 さいたま新都心
7 大宮
たしかに幅が変更されてはいますが、少々わかりにくいです。これを-n
でゼロ埋めして出力すればより明瞭になります。
$ nl -n rz -w 2 utl-kita
01 東京
02 上野
03 尾久
04 赤羽
05 浦和
06 さいたま新都心
07 大宮
駅ナンバリング表示の駅番号を出力する
2桁の数字と駅名を表示したら、あの見慣れた表示も出力したくなりますよね。宇都宮線・高崎線の略線記号「JU」を付加すれば、駅ナンバリング表示の駅番号を出力することができます。プリフィックスの付加には、sed
(Stream EDitor)というテキストを編集するコマンドを組み合わせます。
$ nl -n rz -w 2 utl-kita | sed 's/^/JU/'
JU01 東京
JU02 上野
JU03 尾久
JU04 赤羽
JU05 浦和
JU06 さいたま新都心
JU07 大宮
sed
にも軽く触れておくと、s/^/JU/
の部分は、テキストを置換するs
コマンドで、正規表現^
(行頭)にマッチする部分をJU
に置き換えるという意味です。/
はただの区切り文字なので、sed
の文法上はs@^@JU@
などとしても同じ意味になります。
幅が十分でない場合
さきほどBSDのマニュアルで差分があった部分です。しっかり検証しておきましょう。6桁から7桁になるとき、つまり999999
から1000000
になる部分を出力して試してみます。
まずはcoreutilsから。
$ yes | head -n 1000000 | nl | tail -n 2
999999 y
1000000 y
7桁の数字もきちんと出力されています。もちろん-w
でデフォルト以外の桁数を指定しても同様の挙動になります。
$ yes | head -n 100 | nl -w 2 | tail -n 2
99 y
100 y
busyboxでも試してみましょう。
$ yes | head -n 100 | busybox nl -w 2 | tail -n 2
99 y
100 y
他のコマンドにも触れておくと、yes
の出力「y」をhead
で1000000行あるいは100行を切り取り、nl
で行番号を付加してからtail
で最後の2行だけを出力しています。
続いてBSD系のnl
ではどうでしょうか。macOSのnl
で試してみます。
$ yes | head -n 1000000 | nl | tail -n 2
999999 y
000000 y
どうやら本当に6桁を超えると上位の桁が切り捨てられるようです。つまり**BSD系のnl
では-w
の設定なしに100万行を超える行番号を正しくカウントすることはできません。**念の為に内部的に行番号が正しく保持されているかどうか確認してみましょう。同じ条件で幅を7桁にしてみます。
$ yes | head -n 1000000 | nl -w 7 | tail -n 2
999999 y
1000000 y
この場合はきちんと7桁の数字が出力されました。行番号自体は正しく保持されているようです。
以上の検証結果をまとめると、coreutilsとbusyboxのnl
では-w
は最小の桁数を指定しており、桁が大きくなった場合その幅は可変です。一方で、BSD系のnl
では-w
は固定の桁数を指定しており、その幅を越えた場合は上位の桁が切り捨てられます。このようにnl
は実装によって桁の取り扱いが異なり、-w
の設定値を意識しなければならない場面もありそうです。