- Linux
Linux catとheadコマンドの使い方|行番号・先頭n行の表示
catは「ファイルの中身を全部そのまま出す」コマンド、headは「先頭のn行(既定は10行)だけ出す」コマンドです。 小さな設定ファイルを確かめるなら cat ファイル名、大きなログの冒頭だけ見たいなら head -n 20 ファイル名 と覚えておくと、ほとんどの場面で用が足ります。
この記事では、cat と head の主要オプションをすべて Ubuntu 24.04(GNU coreutils 9.4)で動かし、出力をそのまま載せています。 「先頭n行」「末尾n行を除く」「10〜20行目だけ」「行番号付き」「複数ファイルの先頭」といった目的別のコピペ集、tail・less・nl との使い分け表、macOS(BSD版)で動きが変わるオプションまで1ページにまとめました。macOS での動作は今回の環境では動かせなかったため、該当箇所に「未実行」と明記しています。
catとheadの早見表
やりたいことから探せる逆引き表です。 すべて下の「検証に使ったファイル」で動かして確認しています。
| やりたいこと | コマンド | 補足 |
|---|---|---|
| 中身を全部表示 | cat a.txt |
小さなファイル向き |
| 行番号を付けて表示 | cat -n a.txt |
空行にも番号が付く |
| 空行以外に行番号 | cat -b a.txt |
nl a.txt と同じ数え方 |
| 連続する空行を1行に | cat -s a.txt |
-n と組み合わせて cat -ns |
| タブ・行末・制御文字を見える化 | cat -A a.txt |
タブは ^I、行末は $ |
| 複数ファイルをつなげて保存 | cat a.txt b.txt > ab.txt |
連結(concatenate)が名前の由来 |
| 先頭10行 | head app.log |
既定は10行 |
| 先頭n行 | head -n 3 app.log |
head -3 でも同じ |
| 末尾n行を除いた残り | head -n -5 app.log |
GNU版の書き方 |
| 先頭nバイト | head -c 12 app.log |
1K、1M の単位も可 |
| 複数ファイルの先頭 | head -n 2 a.txt b.txt |
==> 名前 <== の見出し付き |
| 見出しなしで複数ファイル | head -q -n 2 a.txt b.txt |
そのまま連結したいとき |
| 10〜12行目だけ | sed -n '10,12p' app.log |
head -n 12 | tail -n +10 でも可 |
| 行番号付きで先頭3行 | cat -n app.log | head -n 3 |
番号は元ファイルの行番号 |
| n行目から最後まで | tail -n +28 app.log |
head ではなく tail の担当 |
| 末尾n行 | tail -n 2 app.log |
ログの最新部分 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Linux catとheadコマンドの使い方|行番号・先頭n行の表示」
検証に使った環境とファイル
記事中の実行結果は、次の環境とファイルで出したものです。 同じコマンドを貼れば同じ出力になります。
| 項目 | 内容 |
|---|---|
| OS | Ubuntu 24.04.4 LTS |
| cat / head / tail / nl | GNU coreutils 9.4 |
| less | 590 |
| シェル | bash 5.2.21 |
| 比較用 | BusyBox 1.36.1(Alpine などの軽量環境で使われる実装) |
# 30行のログ(line 1 〜 line 30)
seq 1 30 | sed 's/^/line /' > app.log
# タブ区切り・空行2つ・行末に空白があるファイル
printf 'id\tname\n1\tpen\n\n\n2\tnote \n' > items.tsv
# 3行ずつの小さなファイル
printf 'alpha\nbeta\ngamma\n' > a.txt
printf 'one\ntwo\nthree\n' > b.txt
cat・head・tail・less・nlの使い分け
「全部か、一部か」「流すか、めくるか」で選びます。 5つとも「ファイルの中身を見る」コマンドですが、得意な範囲が違います。
| コマンド | 表示する範囲 | 向いている場面 | 代表的な書き方 |
|---|---|---|---|
| cat | 全部を一気に出力 | 数十行までの設定ファイル、ファイルの連結、パイプの入口 | cat conf.txt |
| head | 先頭から n 行 / n バイト | 大きなファイルの冒頭、CSVの見出し行、コマンド出力の最初だけ | head -n 5 data.csv |
| tail | 末尾から n 行、または n 行目以降 | ログの最新部分、追記の監視(-f) |
tail -n 50 app.log |
| less | 1画面ずつ、前後に移動・検索 | 長いファイルを読む、検索しながら読む | less app.log |
| nl | 全部に行番号を付けて出力 | 番号の書式(桁数・区切り)を整えたいとき | nl -ba a.txt |
cat と head は「出力して終わる」コマンドなので、パイプでほかのコマンドにつなげたり、リダイレクトでファイルに保存したりできます。less は画面の中で読むためのコマンドで、キー操作で前後に移動します。この違いを押さえると、スクリプトの中では cat / head / tail、人が読むときは less という分け方が自然に決まります。
less でよく使うキーは次の5つです。
| キー | 動き |
|---|---|
スペース / b |
1画面進む / 戻る |
/文字列 |
下方向に検索(n で次、N で前) |
g / G |
先頭へ / 末尾へ |
-N |
行番号の表示を切り替える |
q |
終了 |
判断に迷ったら、次の順で考えると決めやすくなります。
| 質問 | はい | いいえ |
|---|---|---|
| 1画面に収まる長さか | cat |
次の質問へ |
| 見たいのは先頭だけか | head |
次の質問へ |
| 見たいのは末尾だけか | tail |
次の質問へ |
| 途中を探しながら読みたいか | less(/文字列 で検索) |
sed -n '開始,終了p' で範囲指定 |
catコマンドの使い方(全主要オプションと実行結果)
catのオプション一覧
GNU版 cat の主要オプションは次の9個です。 よく使うのは -n、-b、-s、-A の4つです。
| オプション | 長い名前 | 働き |
|---|---|---|
-n |
--number |
すべての行に行番号を付ける |
-b |
--number-nonblank |
空行以外に行番号を付ける(-n より優先) |
-s |
--squeeze-blank |
連続する空行を1行にまとめる |
-A |
--show-all |
-vET と同じ。制御文字・行末・タブを見える化 |
-E |
--show-ends |
行末に $ を付ける |
-T |
--show-tabs |
タブを ^I で表示 |
-v |
--show-nonprinting |
制御文字を ^M などの形で表示 |
-e |
なし | -vE と同じ |
-t |
なし | -vT と同じ |
中身を全部表示する・複数ファイルをつなげる
ファイル名を並べると、その順につなげて出力します。
$ cat a.txt
alpha
beta
gamma
$ cat a.txt b.txt
alpha
beta
gamma
one
two
three
リダイレクト(>)と組み合わせると、ファイルの連結になります。
$ cat a.txt b.txt > ab.txt; wc -l ab.txt
6 ab.txt
行番号を付ける(cat -n と cat -b の違い)
-n は空行も数え、-b は空行を数えません。 同じファイルで比べると違いがはっきりします。
$ cat -n items.tsv
1 id name
2 1 pen
3
4
5 2 note
$ cat -b items.tsv
1 id name
2 1 pen
3 2 note
エディタやエラーメッセージの「◯行目」と合わせたいときは -n を使います。エディタは空行も1行として数えるためです。
複数ファイルを渡すと、番号は通しで付きます。
$ cat -n a.txt b.txt
1 alpha
2 beta
3 gamma
4 one
5 two
6 three
連続する空行をまとめる(cat -s)
$ cat -s items.tsv
id name
1 pen
2 note
$ cat -ns items.tsv
1 id name
2 1 pen
3
4 2 note
-ns のようにオプションをまとめて書けます。空行がまとめられた後の行に番号が付くため、元ファイルの行番号とはずれる点だけ覚えておいてください。
タブ・行末の空白・改行コードを見える化する(cat -A)
「見た目は同じなのに動かない」ときに役立つのが -A です。 タブは ^I、行末は $ で表示されます。
$ cat -A items.tsv
id^Iname$
1^Ipen$
$
$
2^Inote $
5行目の note と $ の間に空白が2つあることが読み取れます。Windows で作ったファイルの改行(CRLF)は ^M として現れます。
$ printf 'a\r\nb\x01\n' | cat -v
a^M
b^A
| 表示 | 意味 | よくある原因 |
|---|---|---|
^I |
タブ | Makefile や TSV。空白と混ざっていないかの確認に |
$ |
行末 | $ の手前に空白があれば行末の余分な空白 |
^M |
CR(\r) |
Windows の改行コード CRLF |
M- で始まる文字列 |
128以上のバイト | 日本語などのマルチバイト文字(-v を付けたとき) |
最終行に $ がない |
末尾に改行がない | printf 'a\nb' のように最後の改行を省いたファイル |
最後の行に改行がないファイルは、次のように見えます。wc -l は改行の数を数えるので、2行あるように見えても 1 と表示されます。
$ printf 'a\nb' | cat -A
a$
b
$ printf 'a\nb' | wc -l
1
標準入力とつなげる・ファイルを作る
ファイル名の代わりに - を書くと、その位置に標準入力が入ります。
$ echo hello | cat - a.txt
hello
alpha
beta
gamma
ヒアドキュメントと組み合わせると、短いファイルをその場で作れます。
$ cat <<EOF > conf.txt
name=demo
port=8080
EOF
$ cat conf.txt
name=demo
port=8080
catでつまずきやすい3つのエラー
実際に出たメッセージと、その意味・直し方です。
$ cat nofile.txt
cat: nofile.txt: No such file or directory
$ cat /tmp
cat: /tmp: Is a directory
$ cat a.txt >> a.txt
cat: a.txt: input file is output file
| メッセージ | 意味 | 直し方 |
|---|---|---|
No such file or directory |
その名前のファイルがない | ls で名前と場所を確かめる |
Is a directory |
ディレクトリを指定した | 中のファイルを指定する。一覧は ls |
input file is output file |
読むファイルと書くファイルが同じ | 別名に書き出してから mv で置き換える |
もう1つ、メッセージが出ないまま中身が消える書き方があります。
$ cat a.txt > a.txt # エラーは出ず、終了コードも 0
$ wc -c a.txt
0 a.txt
> はコマンドが動く前にシェルが出力先を空にするため、cat が読むときにはもう中身がありません。 同じファイルを書き換えたいときは cat a.txt > a.tmp && mv a.tmp a.txt のように一度別名へ出します。
headコマンドの使い方(全主要オプションと実行結果)
headのオプション一覧
GNU版 head のオプションは6個だけです。
| オプション | 長い名前 | 働き |
|---|---|---|
-n 数 |
--lines=数 |
先頭から指定行数を表示(既定は10) |
-n -数 |
--lines=-数 |
末尾の指定行数を除いた残りを表示 |
-c 数 |
--bytes=数 |
先頭から指定バイト数を表示。K(1024)、M などの単位可 |
-c -数 |
--bytes=-数 |
末尾の指定バイト数を除いた残りを表示 |
-q |
--quiet |
複数ファイルでも ==> 名前 <== の見出しを出さない |
-v |
--verbose |
1ファイルでも見出しを出す |
-z |
--zero-terminated |
行の区切りを改行ではなく NUL 文字にする |
先頭n行を表示する(head -n)
$ head -n 3 app.log
line 1
line 2
line 3
$ head -3 app.log
line 1
line 2
line 3
head -3 は短く書ける形で、GNU版でも BusyBox でも動きます。スクリプトに残すなら、意味が読み取りやすい -n 3 がおすすめです。オプションなしの head app.log は先頭10行を表示します。
ファイルの行数より大きい数を指定しても、エラーにはならず全行が出ます。
$ head -n 100 a.txt
alpha
beta
gamma
末尾n行を除いて表示する(head -n -数)
数の前に - を付けると「最後のn行を除いた残り」になります。 30行のファイルで末尾27行を除くと、先頭3行が残ります。
$ head -n -27 app.log
line 1
line 2
line 3
CSV の最後に付いた合計行を外す、といった用途に便利です。tail 側にも対になる書き方があり、tail -n +数 で「n行目から最後まで」を取り出せます。
| 書き方 | 意味 | 30行のファイルでの結果 |
|---|---|---|
head -n 3 |
先頭3行 | 1〜3行目 |
head -n -3 |
末尾3行を除く | 1〜27行目 |
tail -n 3 |
末尾3行 | 28〜30行目 |
tail -n +3 |
3行目から最後まで | 3〜30行目 |
先頭nバイトを表示する(head -c)
$ head -c 12 app.log
line 1
line
line 1 と改行で7バイト、続く line で5バイト、合わせて12バイトです。行の途中でも指定バイトで切るので、出力の最後に改行が付かないことがあります。
日本語(UTF-8)は1文字が3バイトのことが多く、バイト数で切ると文字の途中で切れます。次の例は「あいう」の先頭4バイトを8進数で表示したもので、「あ」(343 201 202)の後ろに「い」の1バイト目だけが残っています。
$ printf 'あいう\n' | head -c 4 | od -c | head -n 1
0000000 343 201 202 343
文字数で切りたいときは cut -c 1-2 のように文字単位のコマンドを使います。
複数ファイルの先頭をまとめて見る
ファイルを2つ以上渡すと、==> ファイル名 <== の見出しが付きます。
$ head -n 2 a.txt b.txt
==> a.txt <==
alpha
beta
==> b.txt <==
one
two
見出しを外したいときは -q、1ファイルでも見出しを付けたいときは -v です。
$ head -q -n 2 a.txt b.txt
alpha
beta
one
two
$ head -v -n 1 a.txt
==> a.txt <==
alpha
ワイルドカードで「このディレクトリの全 .txt の1行目」を一覧できます。
$ head -n 1 *.txt
==> a.txt <==
alpha
==> ab.txt <==
alpha
==> b.txt <==
one
==> conf.txt <==
name=demo
途中に開けないファイルがあっても、残りは表示されます。終了コードは 1 になります。
$ head -n 2 nofile a.txt
head: cannot open 'nofile' for reading: No such file or directory
==> a.txt <==
alpha
beta
コマンドの出力の先頭だけ見る
head はパイプの後ろに置くと、長い出力の最初だけを取り出せます。
$ ls | head -n 3
a.txt
ab.txt
app.log
$ seq 1 100000000 | head -n 2
1
2
2つ目の例は1億行を作るコマンドですが、head が2行受け取った時点で終わるため、すぐに結果が返ります。前のコマンドは、読み手がいなくなったことを知らせる合図(SIGPIPE)を受けて止まります。
目的別コピペ集
10〜20行目など、途中の行だけを表示する
head と tail を組み合わせる方法と、sed や awk で範囲を指定する方法があります。 10〜12行目を取り出す例です。
# 方法1: 先頭12行のうち、10行目以降
$ head -n 12 app.log | tail -n +10
line 10
line 11
line 12
# 方法2: sed で範囲指定
$ sed -n '10,12p' app.log
line 10
line 11
line 12
# 方法3: awk で行番号の条件
$ awk 'NR>=10 && NR<=12' app.log
line 10
line 11
line 12
| 方法 | 書き方(M〜N行目) | 特徴 |
|---|---|---|
| head + tail | head -n N file | tail -n +M |
head と tail だけで書ける。N行目で読み終える |
| sed | sed -n 'M,Np' file |
短い。大きなファイルでは sed -n 'M,Np;Nq' とすると N 行目で終了する |
| awk | awk 'NR>=M && NR<=N' file |
条件を足しやすい(列の値で絞るなど) |
1行だけ取り出すときも同じ考え方です。
$ head -n 5 app.log | tail -n 1
line 5
$ sed -n '5p' app.log
line 5
行番号付きで先頭・途中を表示する
cat -n を先に通すと、元ファイルの行番号が付いたまま切り出せます。
$ cat -n app.log | head -n 3
1 line 1
2 line 2
3 line 3
$ cat -n app.log | sed -n '10,12p'
10 line 10
11 line 11
12 line 12
順番を逆にすると、切り出した後の行に 1 から番号を振り直します。「元の何行目か」を知りたいときは cat -n を先に書きます。
行番号の見た目を整えたいときは nl が向いています。-b a で空行も数え、-w で桁数、-s で区切り文字を指定します。
$ nl -ba -w3 -s': ' a.txt
1: alpha
2: beta
3: gamma
先頭だけを別ファイルに保存する
$ head -n 2 app.log > top.txt
$ cat top.txt
line 1
line 2
大きな CSV から動作確認用の小さなサンプルを作るときに便利です。見出し行と先頭100件なら head -n 101 data.csv > sample.csv です。
ファイルごとに見出しの形を変えて先頭を表示する
==> 名前 <== 以外の形で区切りたいときは、for で回します。
$ for f in a.txt b.txt; do echo "== $f"; head -n 1 "$f"; done
== a.txt
alpha
== b.txt
one
目的別のまとめ表
| 目的 | コピペ用コマンド |
|---|---|
| 先頭20行 | head -n 20 file |
| 末尾5行を除く | head -n -5 file |
| 見出し行(1行目)を除く | tail -n +2 file |
| 10〜20行目 | sed -n '10,20p' file |
| 行番号付きで全部 | cat -n file |
| 行番号付きで10〜20行目 | cat -n file | sed -n '10,20p' |
| 複数ファイルの1行目 | head -n 1 *.csv |
| 先頭1KB | head -c 1K file |
| 改行コード・タブの確認 | head -n 5 file | cat -A |
| 上下逆に表示 | tac file |
応用例:CSVの見出し・明細・合計行を切り分ける
head と tail を組み合わせると、「1行目は見出し、最後の行は合計」という形のCSVをきれいに切り分けられます。 次の在庫データで試します。
printf 'id,name,qty\n1,pen,12\n2,note,3\n3,clip,40\ntotal,,55\n' > stock.csv
# 見出し行だけ
$ head -n 1 stock.csv
id,name,qty
# 見出しと合計行を除いた明細だけ
$ head -n -1 stock.csv | tail -n +2
1,pen,12
2,note,3
3,clip,40
# 見出しは残したまま、明細を数量の多い順に並べ替える
$ { head -n 1 stock.csv; tail -n +2 stock.csv | head -n -1 | sort -t, -k3,3nr; }
id,name,qty
3,clip,40
1,pen,12
2,note,3
列の名前と番号の対応を確かめたいときは、見出し行を縦に並べて cat -n を通します。「qty は3列目」とすぐにわかるので、cut -d, -f3 や sort -k3 を書く前の確認に使えます。
$ head -n 1 stock.csv | tr ',' '\n' | cat -n
1 id
2 name
3 qty
先頭の数行を、列をそろえた表の形で眺めることもできます。
$ head -n 3 stock.csv | column -s, -t
id name qty
1 pen 12
2 note 3
ファイルの最初と最後だけをまとめて見る
長いログの「始まり」と「終わり」を一度に確かめる書き方です。
$ head -n 2 app.log; echo "..."; tail -n 2 app.log
line 1
line 2
...
line 29
line 30
行番号つきで検索結果を見る
「どの行にあるか」を知りたいときは、cat -n を通してから絞り込む方法と、grep の -n を使う方法があります。出力の形が少し違います。
$ cat -n app.log | grep 'line 2[0-2]$'
20 line 20
21 line 21
22 line 22
$ grep -n 'line 2[0-2]$' app.log
20:line 20
21:line 21
22:line 22
検索が目的なら grep -n のほうが短く書けます。見つけた行番号の前後を読みたいときは、その番号を sed -n '18,24p' に渡すと周辺だけを表示できます。
catでファイルを作る・追記するときの書き方
cat はリダイレクトと組み合わせると、ファイルの作成・上書き・追記にも使えます。 記号1つで結果が変わるので、表で整理します。
| 書き方 | 結果 |
|---|---|
cat a.txt > new.txt |
new.txt を作る。すでにあれば中身を置き換える |
cat a.txt >> log.txt |
log.txt の末尾に追記する。なければ作る |
cat a.txt b.txt > ab.txt |
2つをつなげて ab.txt に保存する |
cat > memo.txt |
キーボードから入力し、Ctrl+D で保存して終わる |
cat <<EOF > conf.txt |
ヒアドキュメントの内容を保存する |
cat < a.txt |
標準入力から読む(cat a.txt と同じ表示) |
> と >> の違いは、すでにあるファイルの中身を残すかどうかです。大事なファイルに書き込むときは、先に cat や head で中身を確かめてから >> を使うと、意図しない置き換えを防げます。bash では set -o noclobber を設定しておくと、> で既存ファイルを置き換えようとしたときにエラーで止めてくれます(未実行)。
GNU版とmacOS(BSD版)・BusyBoxの違い
Linux の cat / head は GNU coreutils、macOS は BSD 由来の実装で、使えるオプションが少し違います。 下の表の Linux 列と BusyBox 列は今回実行した結果です。macOS 列は今回の環境では動かせなかったため未実行で、BSD版について一般に知られている仕様をもとに書いています。手元の macOS では man head、man cat で確かめてください。
| 書き方 | Linux(GNU 9.4)実行済み | BusyBox 1.36.1 実行済み | macOS(BSD版)未実行 |
|---|---|---|---|
head -n 3 |
動く | 動く | 動く |
head -3 |
動く | 動く | 動く |
head -n -5(末尾を除く) |
動く | 動く | 行数に負の値を指定できず、エラーになる |
head -c 12 |
動く | 動く | 動く |
head -c 1K(単位付き) |
動く | invalid number '1K' になる |
数字のみの指定が基本 |
head -q / head -v |
動く | 動く | macOS のバージョンによる |
cat -n / -b |
動く | 動く | 動く |
cat -s |
動く | invalid option -- 's' になる |
動く |
cat -A |
動く | 動く | -A はなく、cat -et で同じ用途 |
cat -e / -t / -v |
動く | 動く | 動く |
tac |
動く | 動く | 標準では入っておらず、tail -r を使う |
どの環境でも動く「末尾n行を除く」の書き方
head -n -5 が使えない環境向けに、行数を数えてから head に渡す方法と、awk で書く方法を用意しておくと安心です。次の2つは Linux で実行して結果を確認しています(8行のファイルで末尾5行を除き、3行が残る例)。
# 方法1: 行数を数えて引き算する
$ n=$(( $(wc -l < s.log) - 5 )); head -n "$n" s.log
line 1
line 2
line 3
# 方法2: awk で n 行ぶん遅らせて出力する
$ awk -v n=5 'NR>n{print buf[NR%n]} {buf[NR%n]=$0}' s.log
line 1
line 2
line 3
最後の1行だけを除くなら sed '$d' file が短く書けます。
macOS で GNU版と同じ書き方を使いたい場合は、Homebrew で coreutils を入れると ghead、gcat という名前で GNU版が使えるようになります(未実行)。シェルスクリプトを Linux と macOS の両方で動かすなら、上の表で3つの列すべてが「動く」になっている書き方を選ぶと、そのまま持ち運べます。
BusyBox は Alpine Linux などの小さなコンテナイメージで使われている実装です。今回の確認では、head -c 1K と cat -s の2つがエラーになりました。コンテナの中でスクリプトを動かすときは、head -c 1024 のように数字だけで書くと、GNU版でも BusyBox でも同じ結果になります。
巨大ファイルやバイナリにcatを使わないほうがよい理由
巨大ファイル:全部読み終わるまで流れ続ける
cat はファイル全体を最後まで出力するので、数百万行のログでは画面が流れ続け、見たい場所を通り過ぎます。 冒頭だけなら head、末尾だけなら tail、探しながら読むなら less が向いています。
約39MB・500万行のファイル(seq 1 5000000 > big.log)で、処理にかかった時間を比べました。
| コマンド | かかった時間(real) | 読む量 |
|---|---|---|
head -n 1 big.log |
0.001秒 | 先頭の一部だけ |
tail -n 1 big.log |
0.002秒 | 末尾の一部だけ |
sed -n '1{p;q}' big.log |
0.002秒 | 1行目で終了 |
cat big.log > /dev/null |
0.008秒 | 全体 |
sed -n '1p' big.log |
0.147秒 | 全体(最後まで読む) |
head と tail は必要な部分だけを読むため、ファイルが大きくなっても時間がほとんど変わりません。sed -n '1p' のように範囲だけ指定した書き方は最後の行まで読み進めるので、大きなファイルでは q(終了)を足すと早く終わります。数値は1回の計測で、ディスクやキャッシュの状態で変わります。
画面に出す場合は、端末が文字を描く時間も加わります。大きなファイルを開くときの目安は次のとおりです。
| 見たい場所 | おすすめ |
|---|---|
| 冒頭 | head -n 50 big.log |
| 末尾 | tail -n 50 big.log |
| 途中を探す | less big.log(/文字列 で検索、G で末尾、q で終了) |
| 条件に合う行 | grep 'ERROR' big.log | head -n 20 |
| 行数だけ知りたい | wc -l big.log |
バイナリファイル:制御文字で端末の表示が乱れる
実行ファイルや画像を cat すると、中に含まれる制御文字を端末が命令として解釈し、文字化けや表示の乱れが起きることがあります。 中身がテキストかどうかは、先に file で確かめられます。
$ file /bin/ls a.txt
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=daa5130f2a41f7fbc8662048f3294f3d439ca7ff, for GNU/Linux 3.2.0, stripped
a.txt: ASCII text
バイナリの冒頭をのぞきたいときは、head -c で量を絞り、cat -v で制御文字を見える形に変えると表示が乱れません。
$ head -c 16 /bin/ls | cat -v
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@
先頭が ^?ELF(0x7F と ELF)なので、Linux の実行ファイルだとわかります。もし端末の表示が乱れたときは、reset と入力して Enter を押すと元に戻せます。
開く前に3つ確かめると、コマンドを選びやすい
初めて見るファイルは、中身を出す前に「行数・サイズ・種類」を確かめると、cat でよいか head にするかをすぐ決められます。
$ wc -l app.log
30 app.log
$ wc -c app.log
231 app.log
$ file app.log
app.log: ASCII text
| 確かめること | コマンド | 判断の目安 |
|---|---|---|
| 行数 | wc -l file |
数十行までなら cat、それ以上は head や less |
| サイズ | wc -c file または ls -lh file |
MB 単位以上なら head / tail / less |
| 種類 | file file |
text と出れば cat で読める。それ以外は head -c 16 file | cat -v |
| 改行コード | head -n 3 file | cat -A |
行末に ^M$ が見えたら CRLF |
この4つを先に見ておくと、画面が流れ続けたり表示が乱れたりする場面をほぼ避けられます。
パイプの入口のcatは省ける
cat file | head -n 3 は head -n 3 file と同じ結果になります。ファイル名を直接渡せるコマンドでは cat を省くと、プロセスが1つ減り、head が必要な分だけ読んで終われます。今回の計測でも cat big.log | head -n 1 と head -n 1 big.log はどちらも一瞬で終わりましたが、書き方としては後者のほうが短く、意図も読み取りやすくなります。
| 書き方 | 同じ結果になる短い書き方 |
|---|---|
cat file | head -n 3 |
head -n 3 file |
cat file | grep ERROR |
grep ERROR file |
cat file | wc -l |
wc -l < file |
cat a b | sort |
そのままでよい(連結は cat の本来の使い方) |
よくある質問
Q. cat -n と nl はどう違いますか?
A. cat -n は空行を含むすべての行に番号を付けます。nl は既定では空行に番号を付けず、cat -b と同じ数え方です。nl -ba とすると cat -n と同じ結果になります。桁数や区切り文字を変えたいときは nl(-w、-s)が便利です。
Q. head -n 5 と head -5 は同じですか?
A. 今回確認した GNU coreutils 9.4 と BusyBox 1.36.1 では同じ結果でした。スクリプトに書くときは、オプションの意味がはっきりする -n 5 をおすすめします。なお head -n -5(末尾5行を除く)とは別の意味なので、-n の後ろの数に付ける符号で区別してください。オプションなしの head は head -n 10 と同じです。
Q. 10行目から20行目だけを表示するには?
A. sed -n '10,20p' file がいちばん短く書けます。head と tail だけで書くなら head -n 20 file | tail -n +10 です。元の行番号も出したいときは cat -n file | sed -n '10,20p' とします。
Q. macOS で head -n -5 がエラーになります。どうすればよいですか?
A. BSD版の head は行数に負の値を指定できないとされています(今回は未実行)。n=$(( $(wc -l < file) - 5 )); head -n "$n" file のように行数を計算して渡す方法なら、Linux でも同じ書き方で動きます。Homebrew の coreutils を入れて ghead -n -5 file とする方法もあります。
まとめ
- cat は全部、head は先頭だけ。 1画面に収まるなら cat、長いファイルは head・tail・less を選ぶ
- 行番号は
cat -n(空行も数える)とcat -b(空行を数えない) を使い分ける。書式を整えるならnl - 先頭n行は
head -n 数、末尾n行を除くならhead -n -数(GNU版・BusyBox で動作を確認) - 途中の行は
sed -n '10,20p'かhead -n 20 | tail -n +10。 元の行番号が欲しいときはcat -nを先に通す - タブ・行末の空白・CRLF の確認は
cat -A。 macOS ではcat -etが同じ用途(未実行) - 同じファイルへの
cat a.txt > a.txtは中身が空になる。 別名に出してからmvで置き換える - バイナリは
fileで種類を確かめ、のぞくときはhead -c 16 ファイル | cat -v
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Linux catとheadコマンドの使い方|行番号・先頭n行の表示」
株式会社RJCでは、Linuxコマンドの基本とその仕組みを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。