Knowing how to count the lines of a file or from the output of a command is a must in Linux.
How to count the lines in a file with Linux?
Linux provides the wc command that allows to count lines, words and bytes in a file or from the standard input. It can be very useful in many circumstances, some examples are: getting the number of errors in a log file or analysing the output coming from other Linux commands.
How many errors can you see in the logs of your application? How many unique users have used your application today?
These are just two examples of scenarios in which you need to be able to count the lines of a file.
So, how can you count the lines of a file using Linux?
Let’s find out how!
The Linux Command to Count Lines
The most used command to do that is the wc (word count) command.
Let’s say we want to count the lines in the /var/log/messages file.
This file contains global system messages and it’s very useful to troubleshoot issues with your Linux system.
To count the number of lines we will use the following syntax:
wc -l <filename>
wc -l /var/log/messages
2094 /var/log/messages
The -l flag is used to get the number of lines, the reason for this flag is that the wc command allows to do a lot more than just counting lines…
As you can see in this case the number of lines in the file is 2094.
Counting the Occurrences of a Pattern in a File
Now, let’s say we want to count the number of errors in the same file.
We can use the grep command followed by the wc command using the pipe.
The pipe is used to send the standard output of the command before the pipe to the standard input of the command after the pipe.
grep <patter-you-are-looking-for> <filename> | wc -l
Here the output of the grep command becomes the input of the wc command.
The output of the grep command without pipe would be:
grep ERROR /var/log/messages
Aug 23 14:43:02 localhost firewalld[28104]: ERROR: Failed to load service file 'RH-Satellite-6.xml': PARSE_ERROR: Unexpected element include
Aug 23 14:43:02 localhost firewalld[28104]: ERROR: Failed to load service file 'freeipa-4.xml': PARSE_ERROR: Unexpected element include
So we have two lines that contain the string ERROR.
If we use the pipe followed by the wc command we won’t see anymore the lines but just the number of lines:
grep ERROR /var/log/messages | wc -l
2
Another example….
I want to know how many times the Apache web server on my Linux machine has been restarted.
First we look for all the lines in /var/log/messages containing the word ‘Apache’:
grep -i apache /var/log/messages
Aug 23 13:52:29 localhost systemd[1]: Stopping The Apache HTTP Server...
Aug 23 13:52:30 localhost systemd[1]: Stopped The Apache HTTP Server.
Aug 23 13:52:33 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:53:05 localhost systemd[1]: Stopping The Apache HTTP Server...
Aug 23 14:53:06 localhost systemd[1]: Stopped The Apache HTTP Server.
Aug 23 14:53:06 localhost systemd[1]: Starting The Apache HTTP Server...
...
We use the -i flag in the grep command to ignore the case when looking for a match, so our grep would match lines containing the text ‘apache’ or ‘Apache’.
We can see that Apache logs the following message when it starts successfully:
Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.
So our grep command becomes:
grep -i apache /var/log/messages | grep Started
Aug 22 23:59:25 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:53:06 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:56:35 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 15:02:44 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 15:10:21 localhost systemd[1]: Started The Apache HTTP Server.
Two grep commands?
Yes, you can use the pipe to concatenate multiple commands, even if they are the same command, like in this case.
And finally we can add wc to get the total count:
grep -i apache /var/log/messages | grep Started | wc -l
13
So, our Apache has been restarted successfully 13 times.
You can also get the same result of the command above using the -c flag for the grep command.
The command above becomes:
grep -i apache /var/log/messages | grep -c Started
The wc command can be also used to count the number of lines in multiple files:
wc -l /var/log/messages /var/log/cron /var/log/maillog
2100 /var/log/messages
183 /var/log/cron
0 /var/log/maillog
2283 total
Very useful!
Counting the Number of Files with a Specific Extension
If we want to count the number of files with extension .log inside the /var/log/ directory, we can use:
ls -al /var/log/*.log
-rw-------. 1 root root 0 Feb 24 03:46 /var/log/boot.log
-rw-r--r--. 1 root root 454593 Feb 23 14:40 /var/log/dnf.librepo.log
-rw-r--r--. 1 root root 312448 Feb 24 17:03 /var/log/dnf.log
-rw-r--r--. 1 root root 90680 Feb 24 17:03 /var/log/dnf.rpm.log
-rw-r--r--. 1 root root 20639 Feb 24 15:03 /var/log/hawkey.log
The wildcard *.log is used to match all the files with extension .log.
What do we do if we want to get the actual number of files?
We use once again the pipe and the wc command:
ls -al /var/log/*.log | wc -l
5
The power of wc together with other Linux commands is endless!
Output of the wc Command Without Flags
Let’s execute the previous command:
ls -al /var/log/*.log | wc -l
But this time without passing any flags to the wc command.
What happens?
[myuser@localhost]$ ls -al /var/log/*.log | wc
5 45 321
We see three numbers in the output…what do they represent?
They are the total numbers of lines, words and bytes.
From the previous example we can already see that 5 is the number of lines. Let’s confirm that 45 and 321 are the number of words and bytes.
The -m flag for the wc command allows to get just the number of words:
[myuser@localhost]$ ls -al /var/log/*.log | wc -w
45
And the -c flag to get the number of bytes:
[myuser@localhost]$ ls -al /var/log/*.log | wc -c
321
Count the Lines in a Zipped File in Linux
So far we have seen how to count the lines of files in Linux.
What if I want to count the number of lines in a zipped file?
First of all we can use the zcat command to print the content of a zipped file.
Let’s say we have a zipped file called app_logs.gz, I can use the following command to see its content:
zcat app_logs.gz
To see the number of lines in this file I can simply use the pipe followed by the wc command in the same way we have seen in the previous sections:
zcat app_logs.gz | wc -l
So, no need to use the gunzip command to decompress the file before counting its lines!
This article gives more details about compressing files in Linux.
Count Empty Lines in a File
I have showed you few things you can do with grep, wc and other commands.
And I want to show you something else that can be useful.
Let’s say I want to count the number of empty lines in a file.
The syntax is similar to other commands we have seen so far with a difference in the pattern matched via the grep command to identify empty lines.
The pattern to identify an empty line with grep is:
grep '^$' <filename>
This represents an empty line because ^ is the beginning of the line, $ is the end of the line and there’s nothing between them.
So taking as an example a file called app_error.log, the full command to identify the number of empty lines in this file is:
grep '^$' app_error.log | wc -l
That as we have seen before can also be written using the -c flag for grep:
grep -c '^$' app_error.log
If I want to print the number of lines that are not empty I can simply add the -v flag for the grep command that inverts the sense of the matching.
It basically selects the lines that don’t match the pattern specified:
grep -cv '^$' app_error.log
Makes sense?
Conclusion
There are many ways you can use the wc command on your Linux system.
You have learned how you can use it to count lines in a file…
How to mix it with the grep command using the pipe, to count the occurrences of a specific pattern in a normal file and in a zipped one…
And how to get the number of files in a directory with a specific extension.
And there are so many other ways in which you can use it.
Do you have any ideas? 🙂
Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.
With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for robotics with Raspberry Pi.