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(-ccounts 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 fileprints three numbers in order: lines, words, and bytes. Despite the name "word count," it counts lines and bytes too.
wc is for. It stands for word count, but it actually reports lines, words, and bytes all at once.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.
2. Count Lines Only with -l
Conclusion:
wc -lshows 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:
-wcounts words,-ccounts bytes,-mcounts characters. For multibyte text (like Japanese),-cand-mdiffer.
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).
wc -c printed 10. Is that 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
-mfor characters, and-cwhen 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 -lcounts output lines = item count.ls | wc -landgrep ... | wc -lare the most common forms.
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.
5-2. Count matching lines from a search
# 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 anything —
ls,grep,find, and more
6. Counting Multiple Files and Totals
Conclusion: Pass multiple files and
wcprints one line each, then atotalline 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...wcopened the file, so it labels which filewc -l < file... the shell streams the content in, sowcnever 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.
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