1

When you use grouped commands in a sed script, is there a way to reference the first and last line of the range you're in?

I want to be able to print the first and last line of a range as well as selected lines between those.

#n
/StartLinePattern/,/EndLinePattern/{
  /PatternOfSubLineToPrint/p;
}

I know that I can solve this by including another grouped command that matches the first and last lines of the range (again); but it would be cleaner, faster, and more reusable to do something akin to the standard for non-grouped commands.

1p;$p

I tried including the above in the group, but it doesn't work. It appears that 1 and $ are absolute, not relative to the range you're in.

Background

I made a sed script that filters elements out of an XML file. To do this, I use ranges with grouped commands to print certain sub elements within that range. So the script works by printing everything that you want to keep.

#n
/<Parent\>/,<\/Parent>/{
  /<Child1\>/,/<\/Child1>/p;
  /<Child2\>/,/<\/Child2>/p;
  /<SingleLineChild\>/p;
}
Sildoreth
  • 1,884

1 Answers1

2

You could do that by using an empty regex i.e. // as the first regex after the opening {
e.g with an input like:

hello
world
start
inner1
inner2
inner3
end
outer

if you run

sed -n '/start/,/end/{
//p
/inner1/p;/inner3/p
}' infile

it prints

start
inner1
inner3
end

You can see how that works here... Just to repost the important part:

When a REGEX is empty (i.e. //) sed behaves as if the last REGEX used in the last command applied (either as an address or as part of a substitute command) was specified.


If you wanted to exclude either the start of the range or the end you'd just add another test:

sed -n '/start/,/end/{
//{
/start/!p
}
/inner1/p;/inner3/p
}' infile
don_crissti
  • 82,805
  • Yes! This is exactly what I needed, so I'm marking as the accepted answer. It's too bad it doesn't cover the case where you want only the first or last line of the range. – Sildoreth Jan 18 '23 at 18:49
  • @Sildoreth - that's easy to manage, see edit. – don_crissti Jan 19 '23 at 13:55