wc Command: Counting Lines, Words, and Bytes

wc Command: Counting Lines, Words, and Bytes

What You'll Learn

  • How to count lines, words, and bytes at once with wc
  • When to use -l / -w / -c / -m
  • How to write the classic pipe counting pattern like ls | wc -l
  • Why beginners get stuck on "bytes and characters differ" and "the last line isn't counted"

Quick Summary

  • Count everything → wc file
  • Just lines → wc -l
  • Count items → some-command | wc -l
  • Count actual characters (multibyte) → wc -m (-c counts bytes, not characters)

Environment

  • OS: Ubuntu / typical Linux
  • GNU coreutils wc (wc = word count)
  • UTF-8 character encoding assumed

1. What Is wc? Count Everything First

Conclusion: wc file prints three numbers in order: lines, words, and bytes. Despite the name "word count," it counts lines and bytes too.

Lina: Senpai, when I want to know "how many lines is this file?" or "how many words?", do I have to count by hand?
Linny-senpai: That's exactly what wc is for. It stands for word count, but it actually reports lines, words, and bytes all at once.
Lina: So the name is a bit narrower than what it does.

Let's prepare a sample file.

$ cat sample.txt
hello world
linux command
penguin gym

Run wc on it directly.

$ wc sample.txt
 3  6 38 sample.txt

What the three numbers mean (left to right)

Position Number Meaning
1st 3 Lines
2nd 6 Words
3rd 38 Bytes

The filename follows at the end.

Lina: Three numbers at once... I'll get lost about which is which.
Linny-senpai: Just remember the order: lines, words, bytes. In practice you usually want only one of them, like "just the line count." Let's look at the options next.

2. Count Lines Only with -l

Conclusion: wc -l shows just the line count. It's the go-to for counting log lines or list entries.

$ wc -l sample.txt
3 sample.txt

-l stands for line.

The standard way to ask "how many lines is this log?"

# How many lines piled up in the log
$ wc -l /var/log/syslog

3. Words, Bytes, and Characters: -w / -c / -m

Conclusion: -w counts words, -c counts bytes, -m counts characters. For multibyte text (like Japanese), -c and -m differ.

3-1. Words with -w

$ wc -w sample.txt
6 sample.txt

-w is word. It counts chunks separated by whitespace or newlines as one word each.

3-2. Bytes with -c

$ wc -c sample.txt
38 sample.txt

-c looks like it stands for character, but what it actually counts is bytes. That's the first pitfall.

3-3. Characters with -m

$ wc -m sample.txt
38 sample.txt

For ASCII-only files, bytes and characters match (1 character = 1 byte). The difference appears with multibyte text.

Option Mnemonic Counts
-l line Lines
-w word Words
-c Bytes
-m Characters

4. Common Pitfall: Bytes vs Characters for Multibyte Text

Conclusion: In UTF-8 a Japanese character takes 3 bytes. To count characters, use -m (characters), not -c (bytes).

Lina: I counted a file containing "あいう" (3 characters) and wc -c printed 10. Is that a bug?
Linny-senpai: Not a bug. -c counts bytes. In UTF-8, one Japanese character = 3 bytes. So "あいう" = 3 chars × 3 bytes = 9 bytes, plus 1 byte for the trailing newline = 10 total.

Let's see it in action.

$ echo "あいう" > jp.txt
$ wc jp.txt
 1  1 10 jp.txt
# Bytes
$ wc -c jp.txt
10 jp.txt
# Characters (the newline counts as one character too)
$ wc -m jp.txt
4 jp.txt

Beginner trap

  • Wanting a "character count" of multibyte text but using -c, which prints a number roughly 3x larger
  • Use -m for characters, and -c when you need the data size in bytes
  • Both count the trailing newline as one unit

5. The Classic Pipe Counting Pattern

Conclusion: some-command | wc -l counts output lines = item count. ls | wc -l and grep ... | wc -l are the most common forms.

Lina: I can count a file's lines now. But I also want things like "how many files are in this folder?"
Linny-senpai: That's where wc shines. It can also count what it receives through a pipe (|). ls | wc -l tells you "the number of lines ls produced" = the number of files.

5-1. Count files and directories

$ ls | wc -l
12

Each line of ls output is one item, so counting lines gives you the count.

# How many lines in the log contain "error"
$ grep "error" app.log | wc -l
27

grep has its own counting option -c. grep -c "error" app.log does the same thing and is shorter. Keep wc -l as the general-purpose form that works with any command.

Why pipe + wc -l is handy

  • No filename in the output (just a number), so it plugs into further processing cleanly
  • Works with anythingls, grep, find, and more

6. Counting Multiple Files and Totals

Conclusion: Pass multiple files and wc prints one line each, then a total line with the sum.

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

The final total is the sum across all files — handy for measuring a whole project's line count.

7. Common Beginner Mistakes

Conclusion: Character mismatches come from mixing up -c/-m; pass input via redirection to drop the filename; the last line's count depends on the trailing newline.

7-1. The filename gets in the way

wc -l file prints the filename too. When you want just the number, pass the content as standard input with redirection <.

# Filename included
$ wc -l sample.txt
3 sample.txt
# Number only (no filename)
$ wc -l < sample.txt
3

How it works

  • wc -l file ... wc opened the file, so it labels which file
  • wc -l < file ... the shell streams the content in, so wc never learns the filename → number only

7-2. No trailing newline makes the count look short

wc -l counts newline characters. If the last line has no newline, that line isn't counted.

# A file that doesn't end with a newline
$ printf "a\nb\nc" | wc -l
2

It looks like 3 lines (a b c), but there are only 2 newlines, so the result is 2. Remember that well-formed text files conventionally end with a newline.

7-3. The character count for Japanese is too big

As covered in section 4, -c counts bytes. For characters, use -m.

$ wc -m jp.txt   # characters
$ wc -c jp.txt   # bytes (~3x for Japanese)

8. Mini Exercises: Try It Yourself

Conclusion: Three tasks — counting lines, counting items, and counting characters — let you confirm wc basics and pipe usage by hand.

Lina: I've got the knowledge! I want to confirm it hands-on.
Linny-senpai: Great, I prepared three tasks. Try them in your terminal.

Task 1: Count how many lines the following file has.

$ cat << 'EOF' > fruits.txt
apple
banana
orange
grape
EOF
Show hint

The option to count lines is -l (line).

Sample answer
$ wc -l fruits.txt
4 fruits.txt

Task 2: Count how many .txt files are in the current directory.

Show hint

Pipe the output of ls *.txt into wc -l.

Sample answer
$ ls *.txt | wc -l

(the number varies by environment)

Task 3: Count the characters in fruits.txt (not bytes).

Show hint

For character count use -m. -c counts bytes.

Sample answer
$ wc -m fruits.txt

(ASCII text, so -m and -c match here; compare them to see the difference)

9. Copy-Paste Templates

Conclusion: Keep the common forms — lines, items, characters, totals — within reach.

Handy forms to keep around

# Count everything (lines, words, bytes)
wc file.txt

# Lines only
wc -l file.txt

# Number only (no filename)
wc -l < file.txt

# Count items (count a listing)
ls | wc -l

# Count search matches
grep "keyword" file.txt | wc -l

# Character count (multibyte-aware)
wc -m file.txt

# Byte count (data size estimate)
wc -c file.txt

# Total lines across multiple files
wc -l *.txt

Summary: What to Read Next