Wc Command in Linux: 7 Easy Examples, Avoid Mistakes

The wc command counts lines, words, characters and bytes. It is part of GNU coreutils, so it is installed everywhere, and the old version of this post introduced it with screenshots. This rewrite runs wc 9.7 on Debian 13 with small sample files, shows the exact numbers, and tests the two claims where wc is easy to misread: the difference between bytes and characters, and the last line of a file without a final newline. It also fixes the pipeline that was supposed to count file extensions.

Basic wc command output and options

The test file a.txt has three lines. wc a.txt printed 3 13 63 a.txt: lines, words, bytes. Each option shows one number:

  • wc -l: 3 lines;
  • wc -w: 13 words;
  • wc -c: 63 bytes, and wc -m: 63 characters (the same for plain ASCII);
  • wc -L: 30, the length of the longest line.

With several files, wc adds a line named total: for a.txt vi.txt nof.txt it printed 5 23 118 total. When the data comes from a pipe or from input redirection, wc has no file name to print: cat a.txt | wc printed only the three numbers, and wc -l < a.txt printed only 3. That is the form you want in scripts, because the output is just the number.

Wc command: bytes versus characters

The file vi.txt contains the text xin chào thế giới and đường dẫn. In the container the locale variables were empty, the POSIX locale, and wc -c -m vi.txt printed 39 39: wc counted each byte as a character. With LC_ALL=C.UTF-8 the same command printed 28 39: 28 characters and 39 bytes. So -m gives the right character count only when the locale is a UTF-8 one.

A script run from cron often has no locale, so set it in the script if you count accented text.

Wc command test: bytes versus characters depend on the locale, the last line without newline is not counted, and the extension pipeline has no counts
Three results of the wc command that surprise people.

The wc command and the last line of a file

wc -l counts newline characters, not lines. A file nof.txt with the text no final newline and no newline at the end printed 0 3 16: zero lines, three words. grep -c "" on the same file printed 1. Likewise, printf "\n\n\n" | wc -l printed 3 and an empty input printed 0 0 0. If your files can lack the final newline, use grep -c "" or add 1 when the last byte is not a newline. This is also the reason the log reader in the Zimbra log script post counts lines from the file it actually read.

Tabs count for -L as jumps to the next multiple of eight: the line col1, tab, col2, tab, col3 has 14 characters and wc -L reported 20. The manual describes this in the wc invocation section.

Counting file extensions with the wc command: the old pipeline

The old post used find ./* -type f | rev | cut -d'.' -f1 | rev | sort | uniq "to count the occurrences of each extension" and added | wc -l. Tested on a project folder with three PHP files, two JS files, a README, a file called .hidden and archive.tar.gz, it has three faults:

  1. uniq without -c lists each extension once; it does not count occurrences. The wc -l version counted 4 distinct names.
  2. A file without a dot is listed by its path: the output contained /README, which is not an extension. .hidden counted as an extension called hidden.
  3. find ./* lets the shell expand the pattern, which skips hidden files in the top folder: 7 files against 8 for find . -type f.

A version that counts, with the list sorted by number:

find . -type f -name "*.*" | sed "s/.*\.//" | sort | uniq -c | sort -rn

It printed 3 php, 2 js, 1 hidden and 1 gz. The dot files are still treated as extensions, and .tar.gz is counted as gz; decide what you want before you rely on the numbers.

File names, directories and errors with the wc command

A file called sp ace.txt worked when quoted. For many files with unusual names, pass them as null-terminated names: find . -maxdepth 1 -name "*.txt" -print0 | wc -l --files0-from=- printed one line per file, including './new'$'\n''line.txt' for a name that contains a newline, and a total of 8.

A directory gives wc: proj: Is a directory and exit code 1 (after printing zeros), and a missing file gives wc: missing.txt: No such file or directory with exit code 1. To count lines of code, wc -l *.php printed each file and a total of 4 for two PHP files with two lines each, and find . -name "*.php" -exec cat {} + | wc -l printed the same 4 without the per-file lines.

Common mistakes with the wc command

  • Reading wc -l as "number of lines" for files that may lack a final newline.
  • Using -m in a script without a UTF-8 locale.
  • Parsing the file name out of the output instead of using input redirection.
  • Building a count from uniq without -c.

A short routine for the wc command in scripts

Four habits make wc results reliable. Redirect the file into the command so that the output has no name. Set a UTF-8 locale before you count characters. Use grep -c "" when the last line may lack a newline. And test the pipeline on a small folder that has a file without an extension and a hidden file, as in the lab above. Each of these four points changed a number in the tests.

FAQ

How do I get only the number from the wc command? Redirect the file into wc, as in wc -l < file. The test printed only 3.

Does the wc command need installing? It is in coreutils; the Debian 13 image had version 9.7 without any extra package.

Comments

Popular posts from this blog

How to Play Minecraft Bedrock Edition on Linux: A Comprehensive Guide for Tech Professionals

Linux desktop frozen? My 5 go-to tricks to try - before forcing a hard reboot

The Ultimate Guide: How to Set Up DXVK in Wine on Linux for Enhanced Gaming Performance