Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the "D" command do in sed?

Tags:

sed

I have read the sed manual for the D command. There it says:

D

If pattern space contains no newline, start a normal new cycle as if the d command was issued. Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input.

But I do not know how to use it.

$ seq 5 | sed D

The output is nothing.

like image 706
qin peter Avatar asked Oct 20 '25 03:10

qin peter


1 Answers

Let's consider four examples. While only the last two might be considered useful, they all illustrate how D works.

By default, sed reads its input and puts one line at a time into the pattern. Unless one takes a step to add a newline to the pattern space, the pattern space will never have a newline. In this case, D is just like d and, consequently, this command produces no output:

seq 5 | sed 'D'

We can use a substitute command to put a newline into the pattern space. In the following, we add a newline to the pattern space and then the D command deletes. Because there was a newline, sed starts the cycle over without reading any input. Consequently, the following is an infinite loop:

seq 5 | sed 's/^/dummy line\n/;p; D'  # Infinite loop

Now, let's do something somewhat useful with D. In the example below, we use N to read in a new line, causing two lines to be in the pattern space with a newline separating them. Except on the last line in the input, we ask the D command to delete the older line and sed starts the cycle over. As a consequence, the following sed command behaves like tail -2:

$ seq 5 | sed 'N;$!D'   # Like `tail -2`
4
5

Lastly, let's extend this to print only the last X lines of a file. Taking X=5 as an example, the following prints the last 5 lines of the input:

$ seq 200 | sed ':a; N; 1,5ba; D'  # Like `tail -5`
196
197
198
199
200

The loop :a; N; 1,5ba reads in the first 5 lines of the file into the pattern space. After that, one new line is read by N while D causes the oldest line in the pattern space to be deleted. As a result, the pattern space will always have the newest 5 lines.

(Note also that a GNU-specific feature of the N command is relied upon there, namely to print the pattern space before exiting on the last line of the file.)

The above commands were all tested under GNU sed. For BSD sed, expect to make some minor changes to achieve the same results.

like image 163
John1024 Avatar answered Oct 22 '25 05:10

John1024