Reputation: 11216
File.txt
Start
1
2
3
4
Start
5
6
7
8
I was messing around with sed to work out different ways to get data from between the Start
s.
One script i made was
sed ':2;h;$!N;$b1;/\n.*Start[^\n]*$/{:1;$!x;/5/p;x;s/.*\n//};$!b2;d'
Explanation of script
:2 #A label for the break point
;h #Hold all the lines currently in the pattern buffer, i use this before getting the next line so that it doesn't have the next start.
;$!N # Gets the next line for every line except the last
;$b1 # Breaks to label 1 on the last line. This is to bypass having to see start to enter the block
;/\n.*Start[^\n]*$/ # If start is on the last line of pattern buffer then execute the next block
{ #Start of block
:1 #Label to jump to if end of file
;$!x # If not the last line switch in the hold buffer we got which doesn't include the next `Start`.
;/5/p # Print if this Start section contains `5`
;x #Switch back hold buffer and pattern to get `Start` back
;s/.*\n// #Delete everything up to last line of pattern buffer(leaving just `Start`.
} # End block
;$!b2 # If not end of file go back to label at the start
;d #Deletes anything left in pattern buffer when we reach the end of the file
Outputs
Start
5
6
7
8
Which is correct
But changing the order of $!N;$b1;
to $b1;$!N
makes the script output nothing.
sed ':2;h;$b1;$!N;/\n.*Start[^\n]*$/{:1;$!x;/5/p;x;s/.*\n//};$!b2;d'
I don't know if I'm missing something obvious, or don't really understand the meaning of $
but it seems to me as though this should make no difference as one command only executes on the last line($
) and the other on all other lines, so the ordering shouldn't matter should it?
Any explanations are welcome and if any more info is needed let me know.
Also I DO NOT want a better way of doing this, I just want an explanation of why it is happening.
Upvotes: 1
Views: 155
Reputation: 19375
$!N;$b1
at the line before last first appends, then branches (as it is now the final line), wheras $b1;$!N
doesn't branch, appends, doesn't enter the block. following is $!b2
which isn't taken, followed by d
deleting the pattern. (and ending the script, as there is no more input) – Hasturkun
Upvotes: 1