I want to print the last line of group using sed

Viewed 219

I have file which is shown below

Section1
    George, 1998-1995
     Peter, 1999-1990
     Simon, 1988-1960
Section2
     Gery,  2019-2015
     John,  1984-1983
     Thomson,  1978-1965

When i give Section1 Expected output is Simon, 1988-1960

Like this i have lots of sections. I want to achieve this with sed not using awk.

I tried like this . But it has the line number hard coding. And also it is printing the complete range

sed -n '/Section1/,4{p}'

Here i could able to remove the hardcoding. But unable to print the last line. And also next section name also coming.

sed -n '/Section1/ , /Section./{p}'
4 Answers

A gnu awk solution.

awk -v RS='Section' '$1=="1" {print $(NF-1),$NF}' file
Simon, 1988-1960

By setting Record Selector to Section, awk works in block. Then print the second latest and the latest field of block matching 1, since Section is stripped of.

This might work for you (GNU sed):

sed '$b;N;/\nSection/P;D' file

Make a moving window of two lines and print the first line if the second line is begins Section and always the last line.

For the last line of a specific section use:

sed -n '/^Section1/{:a;h;$!{n;/^\S/!ba};x;s/^\s*//p}' file

You may consider using

sed -n '/^Section1$/,/^Section[0-9]*$/{:a;h;n;/^Section[0-9]*$/!ba;x;s/^[ \t]*//;p}' file > newfile

See the online demo.

Details

  • -n - the switch suppresses default line output mode
  • /^Section1$/,/^Section[0-9]*$/ - a block of lines between a line that is equal to Section1 and a line that fully matches a Section and any 0 or more digits pattern (the next {...} group of commands relates to the range matched with this)
  • :a - sets a label named a
  • h - copies the current line into hold buffer
  • n - discards the current pattern space value and reads the next line into it
  • /^Section[0-9]*$/!ba - if the pattern space value does not match the end block line go back to label a
  • x - else, once we get to the last line, the previous one is in hold space, so x is used to swap hold and pattern space
  • s/^[ \t]*// - remove initial whitespace
  • p - print the pattern space.

Regex:

(Section1)((\n.*,.*)*\n\s*)(?'lastLine'.*)

Test here.

I did not understand exactly what you want to do with the result, so I cannot tell you the exact sed command.

Related