wc (word count) counts lines, words and bytes. On servers it’s mostly used at the end of a pipeline to answer “how many?”: how many requests, errors, files, users or connections.

Basics

wc file.txt
#   120   843  5231 file.txt
#  lines words bytes

Pick what you need:

wc -l file      # lines
wc -w file      # words
wc -c file      # bytes
wc -m file      # characters (differs from bytes for UTF-8 text)
wc -L file      # length of the longest line

Several files give one line each, plus a total:

wc -l /var/log/nginx/*.log

With a filename, wc prints the name too. Read from stdin to get just the number, which is handy in scripts:

wc -l < access.log          # 48211
lines=$(wc -l < access.log)

Counting in pipelines

grep -c ' 500 ' access.log                       # error count (grep can count itself)
grep ' 404 ' access.log | wc -l                  # same idea with wc
awk '{print $1}' access.log | sort -u | wc -l    # unique visitor IPs
ss -tn state established | tail -n +2 | wc -l   # open TCP connections
ps aux | grep -c '[p]hp-fpm'                     # PHP-FPM processes
getent passwd | wc -l                            # user accounts

The [p]hp-fpm trick stops grep from counting its own process.

Counting files:

find /var/www/uploads -type f | wc -l            # files, recursively
find . -maxdepth 1 -type f | wc -l               # files in this directory only

Avoid ls | wc -l for this. It counts names, and filenames containing newlines throw it off. See ls and find.

Lines of code in a project:

find src -name '*.py' -print0 | xargs -0 cat | wc -l

For real code statistics, cloc or tokei separate code, comments and blank lines.

Gotchas

The last line has no newline. wc -l counts newline characters. A file whose last line doesn’t end in a newline shows one line fewer than you’d expect.

Bytes vs characters. wc -c counts bytes. For UTF-8 text, accented letters and CJK characters take 2–4 bytes, so use wc -m to count characters. The result depends on your locale (LANG=C.UTF-8).

Words are whitespace-separated runs. wc -w counts foo-bar as one word and foo bar as two. It’s fine for rough counts, not for precise text analysis.

Header lines. Commands like ps, ss and df print a header. Strip it with tail -n +2 before counting, or the count is one too high.

Live log files keep growing, so the count is a snapshot.

Watch a count change

Combine with watch to monitor something:

watch -n 2 'ss -tn state established | tail -n +2 | wc -l'

See watch.

Compressed logs

zcat access.log.2.gz | wc -l
zgrep -c ' 500 ' access.log.*.gz

Byte size of a file

wc -c reads the whole file. For large files, stat is instant:

stat -c %s bigfile.iso
du -h bigfile.iso

Quick reference

Task Command
Lines wc -l file
Number only wc -l < file
Words wc -w file
Bytes / characters wc -c / wc -m
Longest line wc -L file
Count matches grep -c pattern file
Count unique values … | sort -u | wc -l
Count files find dir -type f | wc -l

Related: sort and uniq, grep and cut.

  • Linux
  • Command Line
  • Basics