1. Overview

In Linux, getting a portion of text from input files is a common operation.

There are two basic and widely used command-line utilities to output some parts of the text from the input: the head command and the tail command.

In this tutorial, we will discuss the typical usages of these two commands through examples.

2. Introduction to the head and the tail Commands

Both the head and the tail commands are members of the GNU coreutils package. They are, by default, installed in all Linux distributions.

As their names imply, the head command will output the first part of the file, while the tail command will print the last part of the file. Both commands write the result to standard output.

In later sections, we’ll take a closer look at each command and learn how to use them through examples.

3. The head Command

The syntax of the head command is pretty straightforward:

head [OPTIONS] FILES

Let’s prepare a file (numbers_en.txt) as the input example to understand the command better:

$ cat numbers_en.txt
one           : 1
two           : 2
three         : 3
four          : 4
...
ninety-seven  : 97
ninety-eight  : 98
ninety-nine   : 99
one hundred   : 100

The file contains English words of numbers from 1 to 100. Thus, the file has 100 lines.

The head command will, by default, write the first ten lines of the input file to the standard output:

$ head numbers_en.txt
one           : 1
two           : 2
three         : 3
four          : 4
five          : 5
six           : 6
seven         : 7
eight         : 8
nine          : 9
ten           : 10

3.1. Output a Specific Number of Lines

With the -n option, we can let the head command output the first n lines instead of the default 10.

For example, if we want to have the first seven lines printed to standard out, we’d use -n 7:

$ head -n 7 numbers_en.txt
one           : 1
two           : 2
three         : 3
four          : 4
five          : 5
six           : 6
seven         : 7

If we pass the -n option together with a number following the , for example -n -x, the head command will print all lines but the last x lines of the file. 

For instance, if we want to ignore the last 97 lines from the file, we’d do -n -97:

$ head -n -97 numbers_en.txt
one           : 1
two           : 2
three         : 3

3.2. Output a Specific Number of Bytes

In addition to displaying text by line, the head command can also print the file content by byte if we pass the -c option.

The usage of the -c option is the same as the -n option except for displaying text byte-wise instead of line-wise.

Let’s see an example of displaying only the first word “one” (3 bytes) from the file:

$ head -c 3 numbers_en.txt
one

3.3. Output Multiple Files

The head command can also handle multiple files. To see this, let’s first prepare another input file numbers_de.txt. This file is very similar to the numbers_en.txt. The only difference is that the words in the file are in German instead of English:

$ cat numbers_de.txt
eins             : 1
zwei             : 2
drei             : 3
vier             : 4
...
siebenundneunzig : 97
achtundneunzig   : 98
neunundneunzig   : 99
(ein)hundert     : 100

Now let’s output the first five lines from both files in one shot:

$ head -n 5 numbers_en.txt  numbers_de.txt
==> numbers_en.txt <==
one           : 1
two           : 2
three         : 3
four          : 4
five          : 5

==> numbers_de.txt <==
eins             : 1
zwei             : 2
drei             : 3
vier             : 4
fünf             : 5

4. The tail Command

The syntax of using the tail command is quite straightforward, too:

tail [OPTIONS] FILES

The tail command will by default write the last ten lines of the input file to the standard output:

$ tail numbers_en.txt 
ninety-one    : 91
ninety-two    : 92
ninety-three  : 93
ninety-four   : 94
ninety-five   : 95
ninety-six    : 96
ninety-seven  : 97
ninety-eight  : 98
ninety-nine   : 99
one hundred   : 100

4.1. Output a Specific Number of Lines

With the -n option, we can let the tail command output the last n lines instead of the default 10.

This example shows how to get the last seven lines from the input file:

$ tail -n 7 numbers_en.txt
ninety-four   : 94
ninety-five   : 95
ninety-six    : 96
ninety-seven  : 97
ninety-eight  : 98
ninety-nine   : 99
one hundred   : 100

If we pass the -n option together with a number following the “+”, for example “-n +x”, the tail command will print starting with the x-th line till the end of the file.

Let’s print from 95th line till the end of the numbers_en.txt file:

$ tail -n +95 numbers_en.txt
ninety-five   : 95
ninety-six    : 96
ninety-seven  : 97
ninety-eight  : 98
ninety-nine   : 99
one hundred   : 100

4.2. Output a Specific Number of Bytes

Similar to the head command, if we pass -c x option to the tail command, it will output only the last x bytes from the input file.

Let’s get the last number 100 from the input file:

$ tail -c 4 numbers_en.txt
100

In the example above, we passed 4 instead of 3 to the -c option. This is because there is an ending linebreak in the last line, and this linebreak occupied 1 byte.

4.3. Output Multiple Files

Like the head command, the tail command can output from multiple input files, too.

Let’s have a look at an example of printing the last five lines from two input files:

$ tail -n 5 numbers_en.txt numbers_de.txt 
==> numbers_en.txt <==
ninety-six    : 96
ninety-seven  : 97
ninety-eight  : 98
ninety-nine   : 99
one hundred   : 100 

==> numbers_de.txt <==
sechsundneunzig  : 96
siebenundneunzig : 97
achtundneunzig   : 98
neunundneunzig   : 99
(ein)hundert     : 100

4.4. Watch a File for Changes

Sometimes the input file we want to check is changing. For example, a running application may append its output to a log file.

If we execute the tail command with the -f option on the changing file, all newly added lines will be appended to standard out.

Next, let’s see a demonstration of this feature.

First, we’ll create a simple shell script append_ts.sh. Every second it appends the current timestamp to a log file (/tmp/timestamp.log), it will append to the log file ten times:

$ cat ./append_ts.sh
#!/bin/bash
for times in {1..10}
do
    echo $(date) >> /tmp/timestamp.log
    times=$(($times+1))
    sleep 1
done

Now, let’s start watching the log file by the tail command, then we execute the script above and observe if the newly append timestamps come to tail‘s output:

20200308_225529

As we expected, all newly appended lines are printed out.

To exit the tail command, we can press Ctrl-C.

5. Use the head and the tail Together

We’ve learned that the head command can give us the first part of a file, while the tail command can output the last part of the input file. But what if we want to get some part in the middle of a file?

To solve this problem, we can combine the two simple commands.

Let’s say we want to get from the 51st to the 55th line from an input file:

$ tail -n +51 numbers_en.txt | head -n 5
fifty-one     : 51
fifty-two     : 52
fifty-three   : 53
fifty-four    : 54
fifty-five    : 55

We can also get the same output by combining the head command and the tail command in a different way:

$ head -n 55 numbers_en.txt | tail -n 5

6. Conclusion

The head and the tail are two simple and straightforward Linux command-line utilities.

In this article, we’ve learned some typical usages of both commands through examples.

If we use the two commands properly, we can easily get the parts of input files for further processing.

1 Comment
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!