3

According to the answers in Stack Overflow question How to use sed/grep to extract text between two words?, we can get text between two words:

sed -n "/first/,/second/p" file

But what if I want to get text between a word and the last line of the file, as in the following?

sed -n "/word/,/lastline/p" file

2 Answers 2

5

Including the last line you'd do:

sed -n '/word/,$p'

That matches the first occurrence of word all the way until the last line and prints all matches.

Not including the last line:

sed '/word/,$!d;$d'

...which deletes negated matches and then deletes the last line.

And to get from only the last match to the last line you have to try a little harder:

 sed -e :n -e '/\n.*word/D;N;$q;bn'

It loops - it never completes the normal sed line cycle but instead appends the next input line to the pattern space buffer and branches back to do so again. But when it has at least two lines in pattern space and the last matches word it deletes everything in the buffer but the line that matches word. On the last line it just quits and breaks the loop. So what gets printed is everything from the last occurring line containing word to the last line.

Hmmm... maybe I made that harder than it has to be:

sed 'H;$x;/word/h;$!d'

With that one every line is appended to hold space. But lines matching word then overwrite hold space. Every line in pattern space that is not the last line is deleted. And on the last line, just after it is appended to hold space, the hold and pattern spaces are exchanged (in case the last line also contains word) and everything from the last time word overwrote hold space is printed.

5
  • Is this one supposed to remove the last line ? sed 'H;$x;/word/h;$!d'
    – user78605
    Commented Aug 19, 2014 at 14:12
  • @Jidder - no, it's not supposed to, it's even supposed to retain two matches if the last line also matches. If you wanted to remove the last line you'd do instead: sed '$x;H;/word/h;$!d' or if you did not want two matches if the last line matches and wanted only the last line in that case: sed 'H;/word/h;$x;$!d'
    – mikeserv
    Commented Aug 19, 2014 at 14:14
  • 1
    Ahh right okay, just wondering, i need to brush up on sed :)
    – user78605
    Commented Aug 19, 2014 at 14:18
  • 1
    Or <file tac | sed /word/q | tac for the last word to end of file (like yours, assuming word is to be found in the file). Commented Aug 19, 2014 at 16:15
  • @StéphaneChazelas - yes - both of my last match versions are very likely to implode if the buffer is not refreshed. I once did this dc thing with its stacks that worked kind of like tac - it was fast, and could seemingly go forever, but I gave it up when researching the answer to this question (which, I've just realized, you also answered) and learned that AIX tail can read a file backwards - and a google or two later and I met tac. I like it very well, but I'm also a bit of a sed masochist.
    – mikeserv
    Commented Aug 19, 2014 at 16:36
2

Could also use awk

Including match to end of file

awk '/word/{x=1}x' file

After first match til end of file

awk 'x;/word/{x=1}' file
1
  • The first one can also be written awk /word/,0 file Commented Aug 19, 2014 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .