Learn sed together (four)

Like awk, sed executes commands on a line-by-line basis. If our operation is designed to multiple lines, then we need to use the parameter "N" to declare.
"N" means the next line of the current operation, and the current line and the next line are regarded as one unit for operation.
For example, take a look at the result of the following command.

sed '=;N' example.txt
# 1
# This is a test file.
# It is the last day of 2018.
# 3
# Hope all you success!
# HAPPY NEW YEAR!

Among them, "=" represents the line number. When sed executes the command, first execute it for the first line, output the line number "1"; then execute "N", and output the second line and the first line as an operation unit; because the second line has been operated , So when executing'=;N' here, starting from the third line, output the line number "3", and then output the third and fourth lines.
If you reverse the order of operations above

 sed 'N;=' example.txt
# 2
# This is a test file.
# It is the last day of 2018.
# 4
# Hope all you success!
# HAPPY NEW YEAR

The above is to merge the two lines into one operation unit, and then output the line number. Note that the line number is the second line.

The above is the case of even-numbered rows, such as odd-numbered rows. Then the last line will end the sed command because the next line is not found.

 sed '$a The last line!' example.txt | sed "N;="
# 2
# This is a test file.
# It is the last day of 2018.
# 4
# Hope all you success!
# HAPPY NEW YEAR!
# The last line!

When the last line was executed, the next line was not found, so the following "=" command will not be executed! This must be paid attention to, otherwise bugs will easily appear.

In the same way, if you want to use 3 rows as an operating unit, you can use two "N"s to represent it.

sed '=;N;N' example.txt
# 1
# This is a test file.
# It is the last day of 2018.
# Hope all you success!
# 4
# HAPPY NEW YEAR!

Application: Combine two lines into one line

For example, merge two adjacent lines that end with an exclamation mark. Is it possible to write the following:

sed '/!$/s/\n//g' example.txt

First find the line ending with the exclamation mark, and then delete the line separator "\n" after the line! However, this method is wrong! ! Because sed is processed in a single line unit, even if you delete the line separator of a line, sed will output the result on a single line. Therefore, the correct writing is:

sed '/!$/{N;s/\n//g}' example.txt
# This is a test file.
# It is the last day of 2018.
# Hope all you success!HAPPY NEW YEAR!

Extension: sed cache

Sed has two types of caching, one is pattern buffer; the other is hold buffer. The pattern cache is the row you select and read at the moment; the temporary cache is more like a long-term storage space. During the execution of sed, you can store some related content in the temporary cache, which can be called anywhere in the subsequent sed execution Content in the cache. There are the following commonly used commands for these two cache operations:

h: Copy the content in the mode buffer to the temporary buffer and overwrite the content in the previous temporary buffer.
H: Add the content in the mode buffer to the temporary buffer and keep the content in the previous temporary buffer.
g: Remain The content in the cache is copied to the mode buffer and overwrites the content in the current mode cache.
G: The content in the temporary cache is added to the mode buffer and the content in the current mode cache is retained.
However, the introduction of these cache concepts makes sed too complicated It’s difficult to understand, so I won’t discuss it in depth. Here is just one example: output all lines in a text in reverse order

sed -n '1!G;h;$p' example.txt 
# HAPPY NEW YEAR!
# Hope all you success!
# It is the last day of 2018.
# This is a test file.

For the first line, use "!" to indicate that G is not executed, because the temporary buffer is blank at this time, and there is no need to add the temporary buffer to the pattern buffer, otherwise there will be one more blank line; then execute h to change the pattern The cache (the entire content of the first line at this time) is added to the temporary cache; "$p" means that the output is executed on the last line, so the output is not executed here.
For the second line, execute G to add the temporary cache (after the first line runs) to the pattern cache. At this time, the pattern cache becomes:

It is the last day of 2018.
This is a test file.

Then execute h to copy the above pattern cache and overwrite the previous temporary cache. At this time, the temporary cache also becomes:

It is the last day of 2018.
This is a test file.

Then execute the following other lines in sequence.
. . .
In the last line, print out the content in the temporary buffer, and complete the retrograde output of a text!
There are more operations on the sed cache, but some are difficult to understand.

===== THE END ====

Reference materials: http://www.grymoire.com/Unix/Sed.html#uh-30

Learn sed together (four)

Guess you like

Origin blog.51cto.com/15069450/2577341