VMware ESXi and vSphere Cluster Management
How to Count Lines in a File in Linux with wc
Learn how to count lines, words, bytes, and characters in Linux files with wc, including multiple files, pipes, redirection, wildcards, and common errors.
The Linux wc command reports counts from text or other file data. Its name means word count, but it can count more than words: lines, words, bytes, characters, and maximum line length.
This lesson focuses on counting newline-delimited lines with wc. It also covers word and byte counts, multiple files, standard input, shell quoting, and common surprises.
What the wc command does
wc accepts one or more file paths as input. With no options, it normally reports three values for each file:
- the number of newline characters, commonly described as lines;
- the number of whitespace-separated words; and
- the number of bytes.
Additional options can request character counts or the length of the longest line. Command results normally go to standard output, also called stdout, which is the terminal unless you redirect it.
Basic wc syntax and output
wc bobs_file.txt
A typical result has this general form:
12 37 241 bobs_file.txt
Read the numeric fields from left to right as lines, words, and bytes. The filename follows the numbers. Do not rely on fixed spacing between columns: whitespace formatting can vary, especially when counts have different numbers of digits.
The byte count is an amount of file data. A byte is an 8-bit unit. In UTF-8 and other multibyte encodings, one visible character can occupy several bytes.
Understanding what counts as a line
The -l count is based on newline characters, not on the visual rows shown by an editor or terminal. A newline character marks the end of a newline-terminated text line.
For example, a file containing three lines in the usual Unix format normally contains three newline characters:
alpha
beta
gamma
A terminal or editor may wrap a long line across several display rows, but wrapping does not add newline characters. Therefore, display width is not the same as the wc -l result.
The final newline is an important edge case. Text after a newline can look like another line in an editor, but if that final piece of text has no terminating newline, wc -l does not add a count for it. Thus a nonempty file containing alpha with no final newline can produce zero from wc -l, while alpha\n produces one. This is why a visual line count can appear one greater than the wc -l result.
Line-count edge cases
| File content condition | Expected wc -l behavior | Reason |
|---|---|---|
| Empty file | 0 | There are no newline characters. |
| Text ending in a newline | One count for each newline | Each newline terminates a line. |
| Text with no final newline | The unterminated final text does not add a count | wc -l counts newline characters, not every visual text row. |
| Blank lines | Each blank line terminated by a newline is counted | A blank line still contains a line-ending newline. |
| Windows-style CRLF endings | Usually one line count per CRLF ending | The carriage return and line feed are two bytes, but the line feed supplies the newline counted by wc -l. |
Displaying only line counts
Use -l when you only need the number of newline characters:
wc -l bobs_file.txt
The long option is --lines:
wc --lines bobs_file.txt
These forms are preferable to the default report when another command, script, or person only needs the line total.
Words, bytes, characters, and line length
| Option | Long form | Reports | Example |
|---|---|---|---|
-l | --lines | Newline count | wc -l FILE |
-w | --words | Words, defined by wc as sequences of non-whitespace characters separated by whitespace | wc -w FILE |
-c | --bytes | Bytes | wc -c FILE |
-m | --chars | Characters according to the active locale | wc -m FILE |
-L | --max-line-length | Length of the longest line | wc -L FILE |
Options can be used separately or together. For example:
wc -w bobs_file.txt
wc -c bobs_file.txt
wc -l -w -c bobs_file.txt
wc -c reports bytes, while wc -m reports characters. For text containing multibyte UTF-8 characters, these values may differ. Use the option that matches the question you are asking: storage size requires bytes, while a character-oriented analysis may require characters.
Counting multiple files
Give wc several filenames to receive one result per file:
wc -l chapter1.txt chapter2.txt chapter3.txt
The output contains a separate line count for each named file. When more than one input file is supplied, wc normally adds a final aggregate row labeled total.
18 chapter1.txt
24 chapter2.txt
15 chapter3.txt
57 total
The selected option applies to every per-file result and to the total. Without -l, the default report includes lines, words, and bytes for each file and for the total.
Using paths, quoting, and wildcards
You can use relative paths, which are interpreted from the current directory, or absolute paths:
wc -l ./reports/today.txt
wc -l /home/alex/reports/today.txt
Quote a filename containing spaces or shell-special characters so the shell passes it as one argument:
wc -l "project notes.txt"
wc -l "reports/[draft].txt"
A glob is a shell filename pattern such as *.txt. The shell expands the pattern before wc runs; wc receives the matching paths, not the pattern itself.
wc -l -- *.txt
The -- marker tells wc to stop interpreting following arguments as options. This protects a matching filename that begins with a hyphen. The glob may match many files, so review the matches when accuracy matters.
Reading from standard input
Standard input, or stdin, is data supplied directly to a command instead of through a named file argument. A pipe sends the standard output of one command to the standard input of the next.
grep -v '^$' notes.txt | wc -l
Here, grep selects nonblank lines and wc -l counts the selected data. The result is not necessarily the total number of lines in notes.txt; it is the number of lines produced by grep.
Input redirection also supplies stdin:
wc -l < bobs_file.txt
When data comes only from standard input, no filename column appears because wc was not given a filename argument.
| Input method | Example | Filename shown? | Notes |
|---|---|---|---|
| Single file argument | wc -l file.txt | Yes | Reports the count and that file's name. |
| Multiple file arguments | wc -l one.txt two.txt | Yes, for each file | Normally adds a total row. |
| Pipeline input | command-producing-text | wc -l | No | Counts bytes received through stdin. |
| Input redirection | wc -l < FILE | No | The shell opens the file and supplies its contents as stdin. |
Errors and limitations
Common file errors
- File does not exist: the name may be misspelled, the path may be wrong, or filename case may differ. Check the location with
pwdand list entries withls. - Unquoted path: spaces can split one filename into multiple arguments. Quote the path.
- Permission denied: the current user may not have read permission, or a directory in the path may not be traversable. Check permissions with
ls -land use an authorized account or approved permission change.
Unexpected wildcard results
A glob can match more files than intended, or no files at all. Preview a pattern before counting:
printf '%s\n' -- *.txt
If the matches are not correct, provide explicit filenames or adjust the pattern.
Line-ending and complexity limitations
Files transferred between operating systems can use different line-ending conventions. CRLF files usually still produce one wc -l count per line because the line feed is present, but carriage returns can affect other tools and may need investigation or normalization.
Do not use a line total alone as a measure of source-code complexity. Blank lines, comments, generated files, vendored dependencies, formatting style, and newline conventions can all change the number without representing equivalent changes in design or difficulty.
Quick reference
wc FILE # lines, words, and bytes
wc -l FILE # lines only
wc --lines FILE # long form of -l
wc -w FILE # words only
wc -c FILE # bytes only
wc -m FILE # characters
wc -l FILE1 FILE2 # each file plus total
command-producing-text | wc -l # count piped input
wc -l < FILE # count redirected input
wc -l -- "FILE WITH SPACES.txt" # safely handle a quoted path
Once you know the basic form, review the Linux file line-counting reference when comparing command forms or troubleshooting a result.