head と tail は Unix 系のコマンドであり、cat の兄貴分ともいえる。
head は先頭の行から指定された行数を表示する。 tail は末尾の行から指定された行数を表示する。
head, tail とも行数の指定がなければ 10 と解される。
よく使っていたのは、ログファイルに対して % tail -f logfile という -f オプションだった。 これで、絶えず更新されるログファイルを監視していた。
では、行数に対応した元素の名前が書いてあるテキスト atoms.txt があったとする。10 行めから 18 行めを表示するにはどうすればよいだろうか。 念のため、行数、すなわち元素番号も書いておく。(10 行めは Ne, 18 行めは Ar でどちらも不活性ガスである)。
1 H 2 He 3 Li 4 Be 5 B 6 C 7 N 8 O 9 F 10 Ne 11 Na 12 Mg 13 Al 14 Si 15 P 16 S 17 Cl 18 Ar 19 K 20 Ca
一つ考えられるのは、まず head で最初から 18 行までを表示し、tail でその後末尾の 9 行を表示する、という方法である。 10 行から始まり 18 行で終わるということは、合わせて 9 行あることに注意する。
% head -n 18 atoms.txt | tail -n 9
sed を使う手がある。ただし、sed の指定方法は独特で、汎用性に欠けるのが残念だ。vi 系のエディタを使っている人だったらなじむだろう。
% sed -n '10,18p' atoms.txt
% awk '10 <= NR && NR <= 18{print}' atoms.txt
ここで、NR は現在読み込んでいるレコードの番号である。
Cygwin を入れるとか、Windows 10 ならば Ubuntu を入れるなどの方法はあるだろうが、
PowerShell を使うのがいいだろう。
% head -n 10 atoms.txt
に相当するのは、
% Get-Content atoms.txt -head 10
である。-head のかわりに -tail を用いることもできる。
head の普通の使い方は先頭の行から指定された行数を表示する。では、先頭から指定された行数を削除してその後の行を出力するにはどうすればよいか。 これは 兄弟コマンドの tail を使う。 たとえば、先頭 5 行を除いて表示するには次のようにする。
$ tail -n +5 foo.txt
同じことは sed でもできる。
$ sed 1,5d foo.txt
では逆に、末尾から指定された行数を削除してその前の行だけを出力するにはどうすればよいか。 head を使えばよいと想定できる。事実、次のようにマイナス行数を指定できる head であれば、可能である。
$ head -n -5 foo.txt
ただし、上記のようにマイナスの行数を指定することは、FreeBSD の head ではできない。
$ head -n -5 foo.txt
head: illegal line count -- -5
head が使えないとなると sed が使えるのではないかと期待してしまう。しかし、残念ながら、末尾の指定した行数を削除するスマートな方法はない。
上記のように、マイナス行数を受け付けない head しかない場合でも、何とかして指定行数を削除したいというならばどうするか。 パズル的な方法ならばある。
$ tail -r foo.txt | tail -n +5 | tail -r
tail -r はテキストファイルの行を末尾行から先頭行へと逆順に出力するコマンドである。tac で実現している処理系もある。
最後の行のみを削除するのならば、次の方法がある。
$
まりんきょ学問所 > コンピュータの部屋 > UNIX 手習い > head と tail