Read

Module 3 · Text, redirection and pipes

Counting with wc

Lines, words and bytes: how wc counts, how to read its columns, and how to get a bare number for scripts.

What you will learn

  • Read the three default columns of wc and select one with -l, -w or -c.
  • Count several files at once and interpret the total line.
  • Get a bare count from stdin and know what wc counts as a line and a word.

wc stands for *word count*, but it counts three things at once: newline characters, words and bytes. Given a file it prints the three numbers followed by the file name; given several files it prints one row per file plus a total row. It is the tool you reach for to answer "how many?" about almost anything, as long as that anything can be turned into lines first.

The options

OptionCountsDetail
-llinesreally newline characters; a last line without \n is not counted
-wwordsruns of non-blank characters separated by spaces, tabs or newlines
-cbytesfile size; an accented letter in UTF-8 is 2 bytes
-Llongest linelength in characters of the longest line

Options combine: wc -lw prints lines and words only. Without options you get -lwc, always in that order (lines, words, bytes) regardless of how you typed the flags. BusyBox's wc has no -m for characters; -c counts bytes, which is the same thing for plain ASCII text.

~% cd /root/lab/l25
l25% cat poem.txt
the quick brown fox
jumps over
the lazy dog
l25% wc poem.txt
        3         9        44 poem.txt
l25% wc -l poem.txt
3 poem.txt
l25% wc -l < poem.txt
3
l25% wc -l a.txt b.txt
        3 a.txt
        5 b.txt
        8 total
l25% ls /etc | wc -l
19
l25% wc -L poem.txt
19 poem.txt

A bare number

When you want to use the count in a script, or compare it, the file name in wc's output gets in the way. Feed the file through stdin instead, either with < or a pipe, and wc prints only the number. wc -l < file is the idiom; cat file | wc -l is the same with one extra process. Combined with command substitution, n=$(wc -l < file) puts the count in a variable, something you will use constantly in the scripting module.

Counting things that are not files

Because wc reads stdin, anything that can be listed can be counted: ls /bin | wc -l for commands in a directory, grep -c aside grep error log | wc -l for matching lines, ps | wc -l for processes (minus one for the header), cat /etc/passwd | wc -l for user accounts. The pattern is always the same: produce one line per item, then wc -l.

Commands in this lesson

CommandWhat it does
wc fileLines, words and bytes of file.
wc -l fileOnly the line count (plus the name).
wc -w fileOnly the word count.
wc -c fileOnly the byte count.
wc -L fileLength of the longest line.
wc -l < fileBare line count, no file name.
cmd | wc -lCount the lines another command prints.

Quiz

  1. In what order does plain `wc file` print its numbers?

    • words, lines, bytes
    • lines, words, bytes
    • bytes, words, lines
  2. How do you get just the number of lines of notes.txt, with no file name?

    • `wc -l notes.txt`
    • `wc -l < notes.txt`
    • `wc -n notes.txt`
  3. A file was written with `printf 'a\nb\nc'`. What does `wc -l` report?

    • 3
    • 2
    • 0
  4. What does `wc -w` consider a word?

    • A run of letters only
    • Any run of non-blank characters separated by whitespace
    • Anything found in the dictionary

Practice

  1. /root/lab/l25/poem.txt is a short text. Store its number of words, and only the number, in /root/lab/l25/words.txt.

  2. In /root/lab/l25 there are a.txt and b.txt. With a single wc command, write the line count of both files (including the total row) into /root/lab/l25/counts.txt.

  3. Print only the number of bytes in /etc/passwd, without the file name.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.