The p command prints the input buffer, not the hold buffer.
You can use one of the g G x commands to get the hold buffer to the input buffer.
To just print the hold buffer without modifying the input buffer you can use two x (swap) commands:
sed -n '2!h; x; p; x'
Without the -n option there is a default print of the input buffer at the end of each input cycle.
man pages say pattern space, I say input buffer. Filled with one input line at the beginning of each cycle.
man pages say hold space, I say hold buffer. Filled by h H x commands.
A p command at the end of the sed code (script) prints the imput buffer, and the "default print" prints the inbut buffer again. So it is printed twice.
sed loops over the input, runs the code for each cycle.
At the beginning of a cycle one input line is put into the input buffer.
Then the code runs.
At the end of a cycle there is a "default print" of the input buffer, unless suppressed by a -n option.
Let me explain with the detailed comments as below. Here I have step-wise executed 2!h, then 2!h with p, then 2!h;x , then 2!h; x with p, up to which its pretty clear.
But as I do , 2!h; p; x; p , the first print should have o/p 6 lines , and the other p also 6 lines(total 12 lines), but o/p is 9 lines which I do not understand.
linux$ sed '2!h' file1
a (default print)
b (default print)
c (default print)
linux$ sed '2!h;x;' file1
a (default print)
a (default print)
c (default print)
linux$ sed '2!h;p' file1
a (default print)
a (explicit print)
b (default print)
b (explicit print)
c (default print)
c (explicit print)
linux$ sed '2!h;x;p' file1
a (default print)
a (explicit print)
a (default print)
a (explicit print)
c (default print)
c (explicit print)
l
inux$ sed '2!h;p;x;p' file1
a
a
a
b
a
a
c
c
c
expected as :
a (default print of 2!h)
a (explicit print of 2!h for p after 2!h)
b (default print of 2!h)
b (explicit print of 2!h for p after 2!h)
c (default print of 2!h)
c (explicit print of 2!h for p after 2!h)
a (default print of x)
a (explicit print of x for p after x)
a (default print of x)
a (explicit print of x for p after x)
c (default print of x)
c (default print of 2!h for p after x)
As the extension of ongoing discussion, I just got that about the p option of regular sed operation of print (like substitute, quit , delete etc.) Is it a part of these buffer commands (H,h,G,g,x etc.) or in a different scope.
Does p here also works same, or it gives default o/p (rather than explicit) as we have to use p , if no other action is used.
This because when I used p in pattern matching with -n , then the o/p of p was suppressed.
Regarding the /a/, it is a line selector (or address) that behaves like an if clause. If the regular expression in // matches then run the following command, here a p.
Another one is a line number: 2p
If line 2 then print.
The selector can be negated by a following ! 2!p
And 2!h
is: if not line 2 then copy to hold buffer.
After I put this , I realized this remains no more a question, as I understand that p is printing as per the condition and so p's output is not being really suppressed, but the default of the if condition , showing the internal buffer with all 3 lines.