We have already discussed the use of pattern and hold buffer. In this
chapter, we are going to explore more about their usage. Let us discuss
the n command which prints the pattern space. It will be used in conjunction with other commands. Given below is the syntax of then command.
Let us consider there are three SED commands before n and two SED commands after n as follows:
The hold buffer holds data, but SED commands cannot be applied directly on the hold buffer. Hence, we need to bring the hold buffer data into the pattern buffer. SED provides the x command to exchange the contents of pattern and hold buffers. The following commands illustrate the x command.
Let us slightly modify the books.txt file. Say, the file contains book titles followed by their author names. After modification, the file should look like this:
In the first pass of the command, SED reads the first line, i.e., A Storm of Swords into the pattern buffer and checks whether it contains the pattern Paulo or not. As the pattern match does not succeed, it copies this line to the hold buffer. Now both the pattern buffer and the hold buffer contain the same line i.e., A Storm of Swords. In the second step, it checks whether the line contains the pattern Paulo or not. As the pattern does not match, it does not do anything.
In second pass, it reads the next line George R. R. Martin into the pattern buffer and applies the same steps. For the next three lines, it does the same thing. At the end of the fifth pass, both the buffers contain The Alchemist. At the start of the sixth pass, it reads the line Paulo Coelho and as the pattern matches, it does not copy this line into the hold buffer. Hence, the pattern buffer contains Paulo Coelho, and the hold buffer contains The Alchemist.
Thereafter, it checks whether the pattern buffer contains the pattern Paulo. As the pattern match succeeds, it exchanges the contents of the pattern buffer with the hold buffer. Now the pattern buffer contains The Alchemist and the hold buffer contains Paulo Coelho. Finally, it prints the contents of the pattern buffer. The same steps are applied to the pattern The Pilgrimage.
The h command destroys the previous contents of the hold buffer. This is not always acceptable, as sometimes we need to preserve the contents. For this purpose, SED provides the H command which appends the contents to the hold buffer by adding a new line at the end. The only difference between h and H command is, the former overwrites data from the hold buffer, while the later appends data to the hold buffer. Its syntax is similar to the h command.
Thereafter, it checks whether the pattern space contains the pattern Paulo. As the pattern match succeeds, it first prints the contents of the pattern space, i.e., Paulo Coelho, then it copies the hold buffer to the pattern buffer. Hence, both the pattern and hold buffers contain The Alchemist. Finally, it prints the contents of the pattern buffer. The same steps are applied to the pattern The Pilgrimage.
Similarly, we can append the contents of the hold buffer to the pattern buffer. SED provides the G command which appends the contents to the pattern buffer by adding a new line at the end.
[address1[,address2]]nLet us take an example.
[jerry]$ sed 'n' books.txtWhen the above code is executed, it will produce the following result:
1) A Storm of Swords, George R. R. Martin, 1216 2) The Two Towers, J. R. R. Tolkien, 352 3) The Alchemist, Paulo Coelho, 197 4) The Fellowship of the Ring, J. R. R. Tolkien, 432 5) The Pilgrimage, Paulo Coelho, 288 6) A Game of Thrones, George R. R. Martin, 864The n command prints the contents of the pattern buffer, clears the pattern buffer, fetches the next line into the pattern buffer, and applies commands on it.
Let us consider there are three SED commands before n and two SED commands after n as follows:
Sed command #1 Sed command #2 Sed command #3 n command Sed command #4 Sed command #5In this case, SED applies the first three commands on the pattern buffer, clears the pattern buffer, fetches the next line into the pattern buffer, and thereafter applies the fourth and fifth commands on it. This is a very important concept. Do not go ahead without having a clear understanding of this.
The hold buffer holds data, but SED commands cannot be applied directly on the hold buffer. Hence, we need to bring the hold buffer data into the pattern buffer. SED provides the x command to exchange the contents of pattern and hold buffers. The following commands illustrate the x command.
Let us slightly modify the books.txt file. Say, the file contains book titles followed by their author names. After modification, the file should look like this:
[jerry]$ cat books.txtOn executing the above code, you get the following result:
A Storm of Swords George R. R. Martin The Two Towers J. R. R. Tolkien The Alchemist Paulo Coelho The Fellowship of the Ring J. R. R. Tolkien The Pilgrimage Paulo Coelho A Game of Thrones George R. R. MartinLet us exchange the contents of the two buffers. For instance, the following example prints only the names of authors.
[jerry]$ sed -n 'x;n;p' books.txtOn executing the above code, you get the following result:
George R. R. Martin J. R. R. Tolkien Paulo Coelho J. R. R. Tolkien Paulo Coelho George R. R. MartinLet us understand how this command works.
- Initially, SED reads the first line, i.e., A Storm of Swords into the pattern buffer.
- x command moves this line to the hold buffer.
- n fetches the next line, i.e., George R. R. Martin into the pattern buffer.
- The control passes to the command followed by n which prints the contents of the pattern buffer.
- The process repeats until the file is exhausted.
[jerry]$ sed -n 'x;n;x;p' books.txtOn executing the above code, you get the following result:
A Storm of Swords The Two Towers The Alchemist The Fellowship of the Ring The Pilgrimage A Game of ThronesThe h command deals with the hold buffer. It copies data from the pattern buffer to the hold buffer. Existing data from the hold buffer gets overwritten. Note that the h command does not move data, it only copies data. Hence, the copied data remains as it is in the pattern buffer. Given below is the syntax of the h command.
[address1[,address2]]hThe following command prints only the titles of the author Paulo Coelho.
[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;p}' books.txtOn executing the above code, you get the following result:
The Alchemist The PilgrimageLet us understand how the above command works. The contents of books.txt follow a specific format. The first line is the book title followed by the author of the book. In the above command, "!" is used to reverse the condition, i.e., line is copied to the hold buffer only when a pattern match does not succeed. And curly braces {} are used to group multiple SED commands
In the first pass of the command, SED reads the first line, i.e., A Storm of Swords into the pattern buffer and checks whether it contains the pattern Paulo or not. As the pattern match does not succeed, it copies this line to the hold buffer. Now both the pattern buffer and the hold buffer contain the same line i.e., A Storm of Swords. In the second step, it checks whether the line contains the pattern Paulo or not. As the pattern does not match, it does not do anything.
In second pass, it reads the next line George R. R. Martin into the pattern buffer and applies the same steps. For the next three lines, it does the same thing. At the end of the fifth pass, both the buffers contain The Alchemist. At the start of the sixth pass, it reads the line Paulo Coelho and as the pattern matches, it does not copy this line into the hold buffer. Hence, the pattern buffer contains Paulo Coelho, and the hold buffer contains The Alchemist.
Thereafter, it checks whether the pattern buffer contains the pattern Paulo. As the pattern match succeeds, it exchanges the contents of the pattern buffer with the hold buffer. Now the pattern buffer contains The Alchemist and the hold buffer contains Paulo Coelho. Finally, it prints the contents of the pattern buffer. The same steps are applied to the pattern The Pilgrimage.
The h command destroys the previous contents of the hold buffer. This is not always acceptable, as sometimes we need to preserve the contents. For this purpose, SED provides the H command which appends the contents to the hold buffer by adding a new line at the end. The only difference between h and H command is, the former overwrites data from the hold buffer, while the later appends data to the hold buffer. Its syntax is similar to the h command.
[address1[,address2]]HLet us take another example. This time, instead of printing only book titles, print the names of their authors too. The following example prints the book titles followed by their author names.
[jerry]$ sed -n '/Paulo/!h; /Paulo/{H;x;p}' books.txtOn executing the above code, you get the following result:
The Alchemist Paulo Coelho The Pilgrimage Paulo CoelhoWe learnt how to copy/append the contents of pattern buffer to hold buffer. Can we perform the reverse function as well? Yes certainly! For this purpose, SED provides the g command which copies data from the hold buffer to the pattern buffer. While copying, existing data from the pattern space gets overwritten. Given below is the syntax of the g command.
[address1[,address2]]gLet us consider the same example - printing book titles and their authors. This time, we will first print the name of the author and on the next line, the corresponding book title. The following command prints the name of the author Paulo Coelho, followed by its book title.
[jerry]$ sed -n '/Paulo/!h; /Paulo/{p;g;p}' books.txtOn executing the above code, you get the following result:
Paulo Coelho The Alchemist Paulo Coelho The PilgrimageThe first command is kept as it is. At the end of fifth pass, both the buffers contain The Alchemist. At the start of the sixth pass, it reads the line Paulo Coelho and as the pattern matches, it does not copy this line into the hold buffer. Hence, the pattern space containsPaulo Coelho and the hold space contains The Alchemist.
Thereafter, it checks whether the pattern space contains the pattern Paulo. As the pattern match succeeds, it first prints the contents of the pattern space, i.e., Paulo Coelho, then it copies the hold buffer to the pattern buffer. Hence, both the pattern and hold buffers contain The Alchemist. Finally, it prints the contents of the pattern buffer. The same steps are applied to the pattern The Pilgrimage.
Similarly, we can append the contents of the hold buffer to the pattern buffer. SED provides the G command which appends the contents to the pattern buffer by adding a new line at the end.
[address1[,address2]]GNow let us take the previous example which prints the name of author Paulo Coelhofollowed by its book title. To achieve the same result, execute the following SED command.
[jerry]$ sed -n '/Paulo/!h; /Paulo/{G;p}' books.txtOn executing the above code, you get the following result:
Paulo Coelho The Alchemist Paulo Coelho The PilgrimageCan you modify the above example to display the book titles followed by their authors? Simple, just exchange the buffer contents before the G command.
[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;G;p}' books.txtOn executing the above code, you get the following result:
The Alchemist Paulo Coelho The Pilgrimage Paulo Coelho
No comments:
Post a Comment