chaoqun lu
chaoqun lu

Reputation: 1

how to understand dollar sign ($) in sed script programming?

everybody. I don't understand dollar sign ($) in sed script programming, it is stand for last line of a file or a counter of sed? I want to reverse order of lines (emulates "tac") of /etc/passwd. like following:

$ cat /etc/passwd | wc -l  ----> 52        // line numbers

$  sed '1!G;h;$!d' /etc/passwd | wc -l ----> 52 // working correctly

$ sed '1!G;h;$d' /etc/passwd | wc -l ----> 1326    // no ! followed by $

$ sed '1!G;h;$p' /etc/passwd | wc -l ----> 1430    // instead !d by p

Last two example don't work right, who can tell me what mean does dollar sign stand for?

Upvotes: 0

Views: 1717

Answers (1)

John1024
John1024

Reputation: 113864

All the commands "work right." They just do something you don't expect. Let's consider the first version:

sed '1!G;h;$!d

Start with the first two commands:

1!G; h

After these two commands have been executed, the pattern space and the hold space both contain all the lines reads so far but in reverse order.

At this point, if we do nothing, sed would take its default action which is to print the pattern space. So:

  • After the first line is read, it would print the first line.

  • After the second line is read, it would print the second line followed by the first line.

  • After the third line is read, it would print the third line, followed by the second line, followed by the first line.

  • And so on.

If we are emulating tac, we don't want that. We want it to print only after it has read in the last line. So, that is where the following command comes in:

$!d

$ means the last line. $! means not-the-last-line. $!d means delete if we are not on the last line. Thus, this tells sed to delete the pattern space unless we are on the last line, in which case it will be printed, displaying all lines in reverse order.

With that in mind, consider your second example:

sed '1!G;h;$d'

This prints all the partial tacs except the last one.

Your third example:

sed '1!G;h;$p'

This prints all the partial tacs up through the last one but the last one is printed twice: $p is an explicit print of the pattern space for the last line in addition to the implicit print that would happen anyway.

Upvotes: 4

Related Questions