Read a particular line of a file in macOS

1. An overview of the

Reading text files is a common operation when we use the macOS command line. Sometimes we know that X lines in a file contain interesting data, and we just want to read X lines.

2. Problem introduction

The problem is simple. Let’s get a clearer picture with an example.

For example, we have a file called Tao Te Ching.txt:

$nl Daodejing. TXT 1 Chapter 1 on virtue 2 To be virtuous without being virtuous is to be virtuous without being virtuous without being virtuous. To be virtuous without doing anything is to be virtuous without thinking it is to be virtuous without thinking it is to be virtuous without doing anything The head is also a wise man, but the head is also a fool. The head is also a man of great stature, but not a man of truth, but not a man of beauty. So take this 3, Chapter 2, 1:4 In the past, when the Lord thought that the world was coming right, the heaven was not clear and the fear of splitting was not clear. When the Lord thought that the heaven was coming right, the fear of splitting was not clear. When the Lord thought that the heaven was coming right, the fear of splitting was not clear It is not a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness to fear that it is a sign of your greatness Sergeant sergeant of cordierite can smell smell tao if deposit if wu corporal to scent laugh, smile less than thought way based on recommendations of the yue md as cost such as reduced back into the tao as 颣 on DE as bath to light as GuangDe shame as building heart such as losing mass as chongqing generosity without corner = great music and sound elephant punishment hermit is unknown, the only way to begin and good into fourth chapter 7 again and again...Copy the code

As shown in the output above, we used the nl command to print the contents of the file with line numbers.

We know that line 5 of the Tao Te Ching.txt file contains some interesting information. Therefore, we just want to read line 5.

There are many ways to do this on the BSD(Unix-like) command line. In this tutorial, we will explore four approaches:

  • Use the pure Bash command
  • Use sed
  • Run the awk command
  • Use the head and tail commands

3. Run the pure Bash command

To solve this problem, let’s create a shell script getline.sh:

$ cat getLine.sh #! /bin/bash FILE="$1" LINE_NO=$2 i=0 while read line; do i=$(( i + 1 ) test $i = $LINE_NO && echo "$line"; done <"$FILE"Copy the code

The shell script above looks simple enough. It takes two arguments: the file and the target line number.

Basically, it contains only one loop. In the loop, we increment the counter variable $I. When it reaches the given target line number, we print that line. For example, if we run the script using the daodejing.txt file:

$./ getline. sh Tao te Ching. TXT 5 5 Chapter 3 Wen TaoCopy the code

The output shows that the expected line has been printed. Our script works.

If we read the script carefully, we might see that there is room for improvement.

We check every line in the file in a loop, even though we have found and printed the lines we need. Well, if we run this script in tao Te Ching.txt, that’s not a problem. After all, our sample input file is only seven lines long. In the real world, however, we might deal with 7 million lines of files.

So, once you find the target line, it’s good to break the cycle. So, let’s change the script a bit:

$ cat getLine2.sh #! /bin/bash FILE="$1" LINE_NO=$2 i=0 while read line; do i=$(( i + 1 )) case $i in $LINE_NO) echo "$line"; break;; esac done <"$FILE"Copy the code

Once we find the row we need, we break the loop with a case statement. Let’s test it out:

$./ getline2.sh Daodejing. TXT 5 5 Chapter 3 Wen TaoCopy the code

It also works. So, we solved the problem with a little Bash script.

Use 4.The sed command

The sed command is very good at solving this kind of problem. Let’s look at a few compact sed one-liners to do this:

$ sed '5! $sed -n '5p' $sed -n '5p' $sed -n '5p' $sed -n '5pCopy the code

In the first line, “5! D “means to filter all lines except line 5, and in the second command,” -n ‘5p’ “means to print only line 5.

The two single lines worked as we expected. However, like Bash scripts, they iterate over the entire input file. Therefore, if the input files are large, they will take unnecessarily long.

The sed provides a “Q” command, which allows “job-hopping” for further processing. We can place the ‘q’ command in two single lines:

$ sed '5! d; Chapter 3 Wen TaoCopy the code

We can’t tell any difference from the output. So let’s use the SEDsed (a sed debugging utility) tool to run sed with and without “Q” and see how the “Q” command works. First, let’s look at the version without the ‘q’ command:

$ sedsed -d '5! TXT PATT:1, chapter 1 on virtue HOLD:$COMM:5! D PATT:4 To be virtuous without being virtuous is to be virtuous without being virtuous without being virtuous. To be virtuous without being virtuous without doing anything is to be virtuous without thinking. To be virtuous without thinking is to be righteous without thinking is to be righteous without thinking is to be courteous After the righteousness lost the righteousness and then the ceremony of the husband of the faithful moo but also chaos of the first also before the wise way of China but also stupid head is also a big man in its thick and not in its moo in fact not in its China so take the skin of this... 5 chapter iii smell PATT: 6 staff sergeant sergeant of cordierite can smell smell tao if word if wu corporal smell laugh, smile less than thought way based on recommendations of yue md as cost such as reduced back into the tao as 颣 on DE as bath to light as GuangDe shame as building heart such as losing mass as chongqing generosity without corner = great music and sound elephant punishment hermit is unknown, the only way to begin and the good HOLD:$ COMM:5 ! D PATT:7 Chapter 4 Repeated HOLD:$COMM:5! dCopy the code

Then, we can see that the sed command processes the file all the way from the last line (line 7).

Next, we’ll test the sed command with “q” : **

$ sedsed -d '5! d; TXT PATT:I am line 1, chapter 1 on tak HOLD:$COMM:5! d PATT:I am line 2, Virtue is not virtue is not virtue is not virtue is not virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue is not virtue virtue After the righteousness lost the righteousness and then the ceremony of the husband of the faithful moo but also chaos of the first also before the wise way of China but also stupid head is also a big man in its thick and not in its moo in fact not in its China so take the skin of this... PATT:I am line 5, chapter 3 - - HOLD:$COMM: Q I am line 5, Chapter 3 - - -Copy the code

As the debugging output shows, the sed processing stops at line 5.

5. UseawkThe command

The AWK command is another powerful text-processing tool. It can also solve problems in a compact single line: awk ‘NR==5’ Tao Te Ching.txt.

However, as we discussed earlier, we want to stop further processing after line 5 is printed.

Also, awk has the “exit” command to exit the current processing:

$ awk 'NR==5{ print; Chapter 3 Wen TaoCopy the code

So, as the output above shows, we have solved this problem.

6. UseheadandtailThe command

useheadandtailCommand, we can easily get the first and last parts of the file.

If we combine these two commands, we can also read specific lines.

Suppose we want to read line X. The idea is:

  • First, we useheadCommand to get line 1 to X:head -n X input
  • We then pipe the results of the first step totailCommand to get the last line:head -n X input | tail -1

Let’s test this idea for our example:

Head - n 5 moral. TXT | tail - 1 chapter iii to scentCopy the code