1. Overview

When we work with the Linux command line, we often need to extract specific segments from input sources.

In this tutorial, we’ll explore how to extract the first and last lines from an input using a single command. For simplicity, we assume that the input file contains at least two lines.

2. Introduction to the Problem

As usual, let’s understand the problem through an example. Let’s say we’re given an input file:

$ cat file.txt
The FIRST line.

There
    are
        many
            lines.

The LAST line.

As the cat output shows, the file.txt input carries multiple lines. We aim to get the first and last line simultaneously from the input:

The FIRST line.
The LAST line.

Many utilities from the command-line arsenal can help us to achieve the goal. In this tutorial, we’ll address three approaches:

Next, let’s see how to solve the problem at hand.

3. Using the head and tail Commands

When we notice the problem is related to extracting the first and last lines, two commands may come up immediately: head and tail. Indeed, these two commands can easily extract the first line and the last line from the input:

$ head -n1 file.txt
The FIRST line

$ tail -n1 file.txt
The LAST line.

However, with this approach, we’ll need to execute two separate commands to obtain the two lines. This doesn’t align with our objective of obtaining both lines simultaneously.

To get the expected output with these two commands in one shot, we can combine and group the head and tail commands:

$ ( head -n1; tail -n1 ) <file.txt
The FIRST line.
The LAST line.

In the above command, we used (…) to group the head and tail commands so that the command group executes in a subshell. Also, we redirected the input file to the command group and got the desired output.

Alternatively, we can group the two commands using { … } to tell the command group to run in the current shell:

$ { head -n1; tail -n1; } <file.txt
The FIRST line.
The LAST line.

As the examples show, both of these grouping approaches effectively solve this problem, and we don’t experience any differences.

But (…) and {…} groups have some differences as their running environments differ.

4. Using the sed Command

sed is a pretty convenient command-line text processing utility. We can use a sed one-liner to solve the problem straightforwardly:

$ sed -n '1p; $p' file.txt
The FIRST line.
The LAST line.

As the command above shows, we first use the -n option to suppress sed‘s default output. Then, we execute two commands (‘1p*‘ and ‘$p*‘) to print the first and last lines.

Alternatively, we can use sed‘s range address to do the job:

$ sed '2, ${ $ !d; }' file.txt
The FIRST line.
The LAST line.

Let’s quickly walk through the command and understand what it does.

  • 2, ${ … } – From the second line until the last line, we execute the actions in the { … } – we should note that the first line isn’t passed to { … }
  • { $ !d; } – Delete (d) all lines unless (!) it’s the last line ($) in the input

Therefore, only the first and last lines are left after running this command.

5. Using the awk Command

awk is another powerful text-processing tool. So finally, let’s solve this problem using an awk one-liner:

$ awk 'NR == 1; END{print}' file.txt
The FIRST line.
The LAST line.

The code isn’t difficult to understand. When the line number (NR) equals 1, it triggers the default action: printing the current line. Also**, the current record is always the last line in the END block**. Therefore, print outputs the last line.

6. Conclusion

In this article, we’ve learned various approaches to extracting the first and last lines from the input using command-line tools. This task poses no challenge for powerful text-processing tools like sed and awk.

If we solve it using head and tail, we can employ shell techniques such as command grouping and input redirection.