Linux / コマンド / wc - 行・単語・文字数を計算

wcは、ファイルや標準入力の行数、単語数、バイト数、文字数を計算するコマンドです。オプションなしで実行すると、改行数、単語数、バイト数を順に出力し、-l、-w、-c、-mで必要な値だけを選択できます。

簡単な統計だけでなく、ログ件数の確認、検索結果の集計、データファイルの検証、シェルスクリプトの条件判定にもよく使用されます。ただし、wc -lは画面に表示される行ではなく改行文字の数を数える点と、-cと-mの違いを理解して使用する必要があります。

wcコマンドとは?

wcはword countの略で、入力全体を読み込んで改行(newline)、単語、バイト、文字を計算します。ファイルを指定しないか、ファイル名の位置に-を使うと標準入力を読み込むため、他のコマンドとパイプで接続するのに便利です。

GNU wcでは、単語は空白文字で区切られた非空の文字列の連続です。文法的な単語や辞書に登録された単語を判別するわけではないため、句読点が付いた文字列も1つの単語として計算されることがあります。

基本的な文法と出力の読み方

基本文法は次の通りです。角かっこは省略可能な部分を示すため、実際のコマンドには入力しません。

wc [オプション] [ファイル...]

オプションなしでファイルを1つ指定すると、行数、単語数、バイト数およびファイル名が出力されます。

wc notes.txt
12  48  317 notes.txt

上記の結果は、notes.txtに改行文字が12個、単語が48個、バイトが317個あることを意味します。出力フィールドの間隔は入力によって変わる可能性があるため、空白の数に依存して結果を解釈してはいけません。

必要な値を1つだけ見たい場合は、該当するオプションを指定します。

wc -l notes.txt
wc -w notes.txt
wc -c notes.txt

wcの主なオプション

オプション 計算対象 注意点
-l, --lines 改行文字数 最後の行に改行がない場合、その行は含まれません
-w, --words 空白で区切られた単語数 空白の判断はロケールの影響を受ける可能性があります
-c, --bytes バイト数 マルチバイト文字は1文字が複数バイトになることがあります
-m, --chars 文字数 現在のロケールと文字エンコーディングの影響を受けます
-L, --max-line-length 最も長い行の画面表示幅 単純な文字数ではなく、タブや全角文字も考慮します
--files0-from=ファイル NUL文字で区切られたファイル一覧 GNU拡張オプションであり、特殊文字のあるファイル名の処理に便利です

複数のオプションを同時に指定することもできます。出力の順序は、オプションを記述した順ではなく、行数、単語数、文字数、バイト数、最大行長の順で決まります。正確な定義とGNU拡張オプションはGNU Coreutilsのwc公式ドキュメントで確認できます。

行数を正確に数える方法

wc -lは改行文字を数えます

wc -lは論理的な行数ではなく、入力にある改行文字の数を出力します。一般的なテキストファイルは各行が改行で終わるため、結果は行数と同じですが、最後の行に改行がない場合は見える行数より1つ少なくなります。

wc -l access.log

テキストファイルが改行で終わるかどうかは、次のように最後のバイトを確認して判断できます。結果が0aであればLF改行で終わっています。

tail -c 1 notes.txt | od -An -t x1

ファイル名なしで数字だけを出力する

ファイルを引数として渡すと、結果の後にファイル名が表示されます。シェル変数に数字だけを保存したい場合は、標準入力リダイレクトを使用します。

line_count=$(wc -l < notes.txt)
printf '%s\n' "$line_count"

GNU wcは1つの値だけを出力する場合、前の空白なしで表示されますが、他の実装まで考慮するスクリプトであれば、数字の形式を別に検証するのが安全です。

バイト数と文字数の差

-cは保存領域のバイトを数えます

wc -cは入力のバイト数を数えます。ファイルのサイズをバイト単位で確認したり、送信するデータの実際のサイズを計算する場合に適しています。

wc -c document.txt

ファイルシステムが報告するサイズだけが必要な場合、statはファイル全体を読み込まずにメタデータから値を取得できるので、より適していることがあります。

stat -c '%s' document.txt

-mはロケールに従って文字を数えます

wc -mは現在のロケールとエンコーディングを基に文字数を計算します。UTF-8では英字1文字は通常1バイトですが、一般的な漢字やひらがな1文字は3バイトなので、同じファイルでも-cと-mの結果が異なる場合があります。

printf 'Linux 日本語\n' | wc -c
printf 'Linux 日本語\n' | wc -m

UTF-8 を扱うロケールでは、この例の結果はバイト数が 16、文字数が 10 です。末尾の改行も数えます。-m は見た目で一文字に見える結合文字や絵文字のまとまりを数える機能ではありません。

誤ったエンコーディングが混ざったファイルでは文字数が期待と異なることがあります。文字ベースの処理が目的であれば、localeで現在の環境を確認し、ファイルのエンコーディングと一致させてください。

単語数はどのように計算されますか?

wc -wは、空白で区切られた空でない文字列の数を数えます。連続する空白やタブは区切りとして扱われ、句読点を削除したり言語の形態素を解析したりすることはありません。

printf 'one  two\tthree\n' | wc -w
3

空白で単語が明確に区切られない言語の自然言語解析や正確なトークン数の計算には、wc -wは適していない場合があります。この場合、目的に応じた形態素解析器やパーサを使用する必要があります。

複数ファイルの数と合計を確認する

ファイルごとの結果と total 行

複数のファイルを指定すると、各ファイルの結果の後に全体の合計である total 行が追加されます。

wc -l january.log february.log march.log
  120 january.log
  135 february.log
   98 march.log
  353 total

GNU --total オプションで合計方式を指定する

最新の GNU wc は --total=auto、always、only、never により合計行の出力方法を制御できます。合計数値のみが必要な場合は、次のように使用できます。

wc -l --total=only january.log february.log march.log

--totalはGNU拡張機能であり、古いCoreutilsや他のUnix系環境には存在しない場合があります。移植性が必要な場合はwc --helpでサポートの有無を確認し、既存の出力の最後の行を処理する方法を使用してください。

パイプと一緒に使う実践例

検索結果の行数を数える

grepの結果をwc -lに渡すと、一致した行の数を数えることができます。

grep 'ERROR' app.log | wc -l

ファイル単体で一致した行数だけが必要な場合は、grep -c 'ERROR' app.logの方がより直接的です。パイプラインは通常、最後のコマンドの終了状態を返すため、grep や find の読み取り失敗を wc の成功と取り違えないよう、必要に応じてシェルの pipefail 設定や各処理の終了状態を確認します。どちらの方法でも、1行にパターンが複数回存在しても、その行は1度だけ数えられます。詳細な検索方法はLinux grep コマンドの使い方を参照してください。

CSVデータの行数を確認する

最初の行が列名であるCSVファイルの場合、tail -n +2でヘッダーをスキップしてからデータ行を数えることができます。

tail -n +2 data.csv | wc -l

CSVフィールド内に実際の改行が許可されているファイルは、1つのレコードが複数の物理行を占める可能性があるため、この方法ではレコード数を正確に数えることはできません。そのようなファイルはCSVパーサーを使用する必要があります。tailの範囲指定方法はLinux tail コマンドの使い方で確認できます。

特殊文字があるファイル名まで安全に数える

findの通常出力では、ファイル名に改行文字がある場合、項目数を誤って数えることがあります。GNU環境では、ファイル名をNUL文字で区切った後にNULの数を数える方法を使用できます。

find ./logs -type f -name '*.log' -print0 | tr -cd '\0' | wc -c

単にfind ... | wc -lを使用するよりも、空白や改行が含まれるファイル名に安全です。検索パターンである*.logは、シェルが先に展開しないように引用符で囲む必要があります。

実行中のプロセス数を確認する

GNU/Linuxのpsが--no-headersをサポートしている場合は、ヘッダーを除いたプロセス一覧の行を数えることができます。

ps -e --no-headers | wc -l

コマンドを実行した瞬間のスナップショットであり、パイプライン自体のプロセスが含まれるかどうかや、psの実装によって結果は異なる場合があります。監視指標として使用する場合は、専用ツールや/procベースの収集方法を検討してください。

最も長い行の長さを確認する

wc -Lは、最も長い行の単純なバイト数や文字数ではなく、画面に表示される最大幅を計算します。GNU wcは現在のロケールに基づき、幅広文字を考慮し、タブストップ位置を8文字単位で計算します。

wc -L table.txt

したがって、-Lの結果がawk '{ print length }'で求めた文字数やwc -cのバイト数と同じであると仮定してはいけません。コードスタイルチェックのように正確な文字数が必要な作業では、使用するツールの長さの定義をまず確認する必要があります。

多数のファイルを安全に処理する

コマンドラインの長さ制限を回避する

ファイルが非常に多い場合、シェルがワイルドカードを展開した結果、コマンドラインの長さ制限を超えることがあります。GNU wcの--files0-from=-は、NULで区切られたファイルリストを標準入力から読み取ることで、この問題を回避します。

find ./logs -type f -name '*.log' -print0 | wc -l --files0-from=-

このコマンドは各ログファイルの行数と総計を出力します。ファイル名に空白や改行があってもNUL区切りを使用するため、安全に渡せます。

xargsで分割された合計に注意する

find ... | xargs wc -lはファイル数が多いとき、複数回のwc実行に分かれることがあります。この場合、各実行ごとに別々のtotalが生成され、全体の合計をすぐに読むことは難しくなります。GNU環境では、--files0-from=-が全リストを一度に集計する目的により適しています。

シェルスクリプトで使用する際の原則

必要な値だけを要求する

オプションなしのwc出力の複数列を空白で切って使うのではなく、-l、-w、-cのように必要な値だけを要求します。ファイル名も不要であれば入力リダイレクションを使用します。

bytes=$(wc -c < archive.dat)

エラーと0を区別する

空ファイルの結果0とファイルを読み込めなかったエラーは意味が異なります。値だけを保存すると標準エラーや終了状態を見逃すことがあるため、重要な自動化処理ではコマンドの成功可否も一緒に確認します。

if count=$(wc -l < input.txt); then
  printf 'lines=%s\n' "$count"
else
  printf 'input.txtを読めませんでした.\n' >&2
fi

よく発生する誤解と注意点

wc -l の結果が予想より1つ少ないです

最後の行が改行文字で終わっていない可能性が高いです。wc -l は改行文字を数えるため、最後の不完全な行は含まれません。元の形式を勝手に変更する前に、ファイルを生成したプログラムの出力ルールを確認してください。

日本語が入ると -c と -m が異なります

-c はバイトを、-m は文字を数えます。UTF-8 のようなマルチバイトエンコーディングでは正常な差異です。保存サイズが目的なら -c、ロケールに従った文字数が目的ならエンコードとロケールを確認してから -m を使ってください。

ls の出力でファイル数を数えてもいいですか?

普通のファイル名では ls | wc -l が簡単に見えますが、エイリアス・出力形式・改行を含むファイル名のため、自動化には向きません。ファイル種類と検索深さを明示できる find を使い、任意のファイル名を扱う場合は NUL 区切り方式を選んでください。

よくある質問

wc をオプションなしで実行するとどうなりますか?

基本的に改行数、単語数、バイト数がこの順序で出力されます。ファイルを引数として指定した場合、最後にファイル名も表示されます。

空のファイルではwcの結果はどうなりますか?

内容が全くない空のファイルは行数、単語数、バイト数がすべて0です。改行文字が1つだけあるファイルはwc -l結果が1で、バイト数は使用する改行形式によって変わる場合があります。

wc -wは日本語の単語数も正確に数えますか?

wc -wは言語を分析せず、空白で区切られた文字列を数えます。スペースが入力目的に合っていれば参考値として使用できますが、日本語の形態素や意味単位の正確な単語数は保証しません。

ディレクトリ自体の行数を数えることはできますか?

wcはディレクトリ項目を直接数えるコマンドではありません。findなどで目的のファイル一覧を作り、その結果を集計する必要があります。ファイル名に特殊文字が含まれる可能性がある場合は、改行の代わりにNUL文字を区切りとして使用してください。

まとめ

行数はwc -l、単語数はwc -w、バイト数はwc -c、文字数はwc -mで確認します。オプションなしの出力は改行・単語・バイトの順であり、複数のファイルを指定するとファイルごとの値と合計が表示されます。

正確な結果を得るためには、wc -lが改行文字をカウントする点、バイト数と文字数が異なる場合がある点、ファイル名リストにはNULで区切る必要がある場合がある点を覚えておきましょう。他の基本的なツールも一緒に確認したい場合は、Linuxでよく使うコマンド一覧を参考にできます。