wc コマンド入門 - 行数・単語数・文字数を数える

wc コマンド入門 - 行数・単語数・文字数を数える

この記事でできるようになること

  • `wc` で行数・単語数・バイト数・文字数を数え分けられる
  • `-c`(バイト数)と `-m`(文字数)を取りちがえずに使える
  • `ls | wc -l` のようにパイプで件数を数えられる

前提知識(先に読むと理解しやすい記事)

この記事で学べること

  • wc行数・単語数・バイト数 をまとめて数える基本が分かる
  • -l / -w / -c / -m使い分け が身につく
  • ls | wc -l のように パイプで「件数」を数える 定番形が書けるようになる
  • 初心者がハマりやすい 「バイト数と文字数がずれる(日本語)」「最終行のカウントが合わない」 の理由がわかります

言葉の整理(先に取りちがえを防ぎます)

  • :ファイルの中の 1 行のことです。wc は改行の数で行を数えます。
  • 単語:空白か改行で区切られたひとかたまりです。日本語の「単語」とは数え方がちがう点に注意してください。
  • バイト:データの大きさを表す単位です。ファイルの容量にあたります。
  • 文字:人が読む文字 1 つ分です。日本語の 1 文字は 1 バイトではありません。ここが最大の関門です。
  • 文字コード:文字をデータに置きかえる決まりです。この記事では UTF-8 を使います。「エンコーディング」も同じものを指します。

結論(先に覚える型)

  • とりあえず全部数えたい → wc ファイル
  • 行数だけ欲しい → wc -l
  • 件数を数えたい(一覧の数え上げ) → 何かのコマンド | wc -l
  • 日本語の「文字数」を数えたい → wc -m-c はバイト数なので注意)

前提(対象環境)

  • OS:Ubuntu / 一般的な Linux
  • GNU coreutils の wcwc = word count の略)
  • 文字コードは UTF-8 を想定

1. wc とは何か?まずは全部数えてみる

結論: wc ファイル は「行数・単語数・バイト数」を左から順に 3 つ表示する。名前は word count だが行もバイトも数えられる。

リナ: 先輩、「このファイルは何行あるのか」を知りたいときは、手で数えるしかないのですか。
ライニー先輩: そんなときのためのコマンドが wc だよ。word count の略なんだ。
ライニー先輩: 名前は「単語を数える」だけど、実際は 行数・単語数・バイト数 をまとめて数えてくれる。
リナ: 名前と中身が少しちがうんですね。

サンプルとして次のファイルを用意しよう。

$ cat sample.txt
hello world
linux command
penguin gym

wc にそのまま渡してみる。

$ wc sample.txt
 3  6 38 sample.txt

3 つの数字の意味(左から順番)

位置 数字 意味
1 番目 3 行数
2 番目 6 単語数
3 番目 38 バイト数

右はしにファイル名が付きます。

リナ: 数字が 3 つも出ると、どれが何だかわからなくなりそうです。
ライニー先輩: 順番さえ覚えれば大丈夫。「行・単語・バイト」 の順だよ。
ライニー先輩: それに現場では「行数だけ欲しい」のように 1 種類だけ 使うことが多い。次でオプションを見ていこう。

2. 行数だけ数える -l

結論: wc -l は行数だけを表示する。ログの行数やリストの件数を数えるときの定番。

$ wc -l sample.txt
3 sample.txt

-lline(行)の頭文字です。

ログファイルが何行あるかを知りたいときの定番です。

# エラーログが何行たまっているか
$ wc -l /var/log/syslog

3. 単語数・バイト数・文字数 -w / -c / -m

結論: -w は単語数、-c はバイト数、-m は文字数。日本語など多バイト文字では -c-m の値がずれる。

3-1. 単語数 -w

$ wc -w sample.txt
6 sample.txt

-wword(単語)の頭文字です。空白か改行で区切られたかたまり を 1 単語として数えます。

日本語の文章は空白で区切りません。そのため -w の結果は、人が思う単語数とは一致しません。

3-2. バイト数 -c

$ wc -c sample.txt
38 sample.txt

-ccharacter(文字)に見えます。ところが実際に数えるのは バイト数 です。ここが最初の落とし穴です。

3-3. 文字数 -m

$ wc -m sample.txt
38 sample.txt

英数字だけのファイルなら バイト数と文字数は一致 します。1 文字がちょうど 1 バイトだからです。

ちがいが出るのは日本語のときです。次の章でくわしく見ます。

オプション 数えるもの
-l line 行数
-w word 単語数
-c バイト数
-m 文字数

4. リナの失敗:日本語で「バイト」と「文字数」がずれる

結論: UTF-8 では日本語 1 文字が 3 バイト。文字数を数えたいなら -c(バイト)ではなく -m(文字)を使う。

リナ: 「あいう」という 3 文字のファイルを数えました。すると wc -c10 と出ました。これはバグですか。
ライニー先輩: バグではないよ。-c が数えているのは バイト数 なんだ。
ライニー先輩: UTF-8 という文字コードでは、日本語の 1 文字が 3 バイト になる。だから「あいう」は 3 文字 × 3 バイトで 9 バイト。
ライニー先輩: そこに行末の改行 1 バイトが足されて、合計 10 になるんだ。
リナ: えっ、文字の数とデータの大きさは別ものなんですね。びっくりしました。
ライニー先輩: そう。人が読む文字数を知りたいときは -m を使う。そう覚えておけば混乱しないよ。
リナ: 数字が 3 倍くらいになっていた理由がわかりました。すっきりしました。

実際に見てみよう。

$ echo "あいう" > jp.txt
$ wc jp.txt
 1  1 10 jp.txt
# バイト数
$ wc -c jp.txt
10 jp.txt
# 文字数(改行も 1 文字として数える)
$ wc -m jp.txt
4 jp.txt

初心者あるある

  • 日本語の文字数を数えたいのに -c を使い、3 倍ほどの数字が出て混乱します
  • 文字数を数えたいなら -m です。データの容量を知りたいなら -c です
  • どちらも行末の改行を 1 つ分として数えます

5. パイプで「件数」を数える定番形

結論: 何かのコマンド | wc -l で出力行数=件数を数えられる。ls | wc -lgrep ... | wc -l が頻出。

リナ: ファイルの行数はわかりました。「このフォルダファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。にファイルがいくつあるか」も数えたいです。
ライニー先輩: そこで wc が力を発揮する。wcパイプ(|)で受け取った出力 も数えられるんだ。
ライニー先輩: ls は画面に出すときは何列かに分けて並べる。でもパイプで次のコマンドに渡すときは、1 項目を 1 行にして送るんだ。
ライニー先輩: だから ls | wc -l の行数が、そのままファイルの数になるよ。

5-1. ファイル・ディレクトリの個数を数える

$ ls | wc -l
12

パイプに渡されたときの ls は、1 行に 1 項目を出します。だから行数を数えれば 個数 がわかります。

なお ls は隠しファイルを数えません。名前が . で始まるファイルのことです。含めたいときは ls -A | wc -l と書きます。

5-2. 検索にヒットした行数を数える

# ログから "error" を含む行が何件あるか
$ grep "error" app.log | wc -l
27

grep にも件数を数える -c オプションがあります。grep -c "error" app.log でも同じ結果になり、こちらのほうが短く書けます。

いっぽう wc -l は、どんなコマンドの出力にも使えます。おぼえておくと便利です。

パイプ + wc -l が便利なポイント

  • 出力にファイル名が付きません。数字だけが返るので、そのまま集計に使えます
  • lsgrepfind など どのコマンドの出力でも数えられます

6. 複数ファイルをまとめて数える&合計

結論: 複数ファイルを渡すと 1 行ずつ表示し、最後に total 行で合計を出す。

$ wc -l *.txt
  1 jp.txt
  3 sample.txt
  4 total

最後の total全ファイルの合計 行数です。プロジェクト全体の行数をはかるときに便利です。

7. よくある初心者のつまずき

結論: 文字数のずれは -c/-m 取り違え、ファイル名が邪魔なときはリダイレクトで渡す、最終行のカウントは改行有無で変わる。

7-1. 出力にファイル名が付いて邪魔

wc -l file はファイル名も一緒に出ます。数字だけ欲しい ときは、リダイレクト < を使います。ファイルの中身を標準入力として流しこむ書き方です。

# ファイル名が付く
$ wc -l sample.txt
3 sample.txt
# 数字だけ(ファイル名なし)
$ wc -l < sample.txt
3

仕組み

7-2. 最終行に改行がないと行数が 1 少なく見える

wc -l改行の数 を数えます。最後の行に改行がないと、その行は数えられません。

# 改行で終わらないファイル
$ printf "a\nb\nc" | wc -l
2

画面では a b c の 3 行に見えます。しかし改行は 2 個しかありません。だから結果は 2 です。

テキストファイルは、最後の行も改行で終わらせるのがふつうです。そう覚えておくと混乱しません。

7-3. 日本語の文字数なのに数字が大きすぎる

第 4 章のとおり、-c はバイト数を数えます。文字数を知りたいときは -m を使います。

$ wc -m jp.txt   # 文字数
$ wc -c jp.txt   # バイト数(日本語は約 3 倍)

8. ミニ課題:実際にやってみよう

結論: 行数カウント・件数カウント・文字数の 3 問で、wc の基本とパイプ連携を手で確かめる。

リナ: 知識は入りました。手を動かして確かめたいです。
ライニー先輩: いいね、3 問用意したよ。ターミナルで試してみて。

課題 1:次のファイルが何行あるか数えよう。

$ cat << 'EOF' > memo.txt
りんご
ばなな
みかん
ぶどう
EOF
ヒント 1(方向づけ)を見る

数えたいのは行の数です。行だけを数えるオプションが第 2 章にありました。

ヒント 2(コマンド名)を見る

使うのは wc です。オプションは -l です。

答えを見る
$ wc -l memo.txt
4 memo.txt

課題 2:いまいるディレクトリにある .txt ファイルが何個あるか数えよう。

ヒント 1(方向づけ)を見る

まず .txt の一覧を出します。その一覧が何行あるかを数えれば、それが個数です。

ヒント 2(コマンド名)を見る

ls *.txt の出力をパイプで wc -l に渡します。

答えを見る
$ ls *.txt | wc -l

数字は環境によって変わります。

課題 3memo.txt文字数 を数えよう(バイト数ではなく)。

ヒント 1(方向づけ)を見る

数えたいのは人が読む文字の数です。データの大きさではありません。第 4 章の使い分けを思い出してください。

ヒント 2(コマンド名)を見る

使うのは wc です。オプションは -m です。-c を選ぶとバイト数になります。

答えを見る
$ wc -m memo.txt
16 memo.txt

1 行は「ひらがな 3 文字 + 改行 1 つ」で 4 文字ぶんです。それが 4 行なので合計 16 文字になります。

wc -m は改行も 1 文字として数えます。wc -c memo.txt も実行して、バイト数との差を見くらべてみてください。

9. コピペ用テンプレート

結論: 行数・件数・文字数・合計のよく使う型を手元に置いておく。

よく使う型をまとめておく

# 全部数える(行・単語・バイト)
wc file.txt

# 行数だけ
wc -l file.txt

# 数字だけ欲しい(ファイル名なし)
wc -l < file.txt

# 件数を数える(一覧の数え上げ)
ls | wc -l

# 検索ヒット件数
grep "keyword" file.txt | wc -l

# 日本語の文字数
wc -m file.txt

# バイト数(データ容量の目安)
wc -c file.txt

# 複数ファイルの合計行数
wc -l *.txt

10. 振り返り

リナ: 整理します。-c はバイト数で、-m が文字数。日本語では結果が変わるんですね。
ライニー先輩: そのとおり。UTF-8 では日本語 1 文字が 3 バイトだからね。
リナ: 件数を数えたいときは、コマンドの出力をパイプで wc -l に渡す。ここも覚えました。
ライニー先輩: 完璧だね。行数は改行の数だという点も、あわせて頭に入れておくといいよ。

今日の 3 行まとめ

  1. wc は左から「行数・単語数・バイト数」の順に表示する
  2. 日本語の文字数は -m で数える。-c はバイト数なので数字が大きくなる
  3. 件数を数えたいときは コマンド | wc -l の形にする

まとめ:次に読む

この記事を共有

次の一手