Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get sed to print a range of lines until it sees two consecutive blank lines?

Tags:

sed

I'd like to use a sed script like this

#n
/^TODO/,/^$/p

except that sed should stop printing the range after it comes across two consecutive blank lines, rather than just one blank line. Then it should continue scanning for the next range of interest. In other words, the end of range of interest is defined by two blank lines. I'm not even sure that an address range can handle this sort of requirement, so if there's another way to do this, please let me know.

like image 994
dan Avatar asked Dec 21 '09 04:12

dan


People also ask

How do I print a line between two patterns in Linux?

Using the sed Command. The sed command is a common command-line text processing utility. It supports address ranges. For example, sed /Pattern1/, /Pattern2/{ commands }… will apply the commands on the range of lines.

Which command is used to print the given pattern?

“p” is a command for printing the data from the pattern buffer. To suppress automatic printing of pattern space use -n command with sed. sed -n option will not print anything, unless an explicit request to print is found.


2 Answers

This should stop when it encounters two consecutive blank lines regardless of the odd/even pairing of the blank lines with non-blank lines:

Don't print the two blank lines:

sed -n 'N;/^\n$/q;P;D'

Print one of them:

sed -n 'N;/^\n$/{P;q};P;D'

Print both of them:

sed -n 'N;/^\n$/{p;q};P;D'

Edit:

And here's how you'd make that work in your range:

sed -n '/^TODO/,${N;/^\n$/q;P;D}'

Edit 2:

Per dan's (the OP) comments and edited requirements, this seems to work to find the pattern in a range that ends in two blank lines, multiple times in a file:

sed -n '/^TODO/,/^$/{H;N;/^\n$/{b};p}'
like image 126
Dennis Williamson Avatar answered Sep 30 '22 00:09

Dennis Williamson


This may work for you:

sed -n '/TODO/{:a;N;/\n\n$/s///p;Ta}' file

This will strictly adhere to the OP question and only print the range less the two newlines if each range includes two consecutive newlines.

If an end of file will also signify the end of such a range, use:

sed -n '/TODO/{:a;p;n;/^$/!ba;n;//b;x;p;x;ba}' file

N.B. The use of the hold space to supply a single blank line when it is not followed by another.


Also the first solution can print either two newlines:

sed -n '/TODO/{:a;N;/\n\n$/!ba;p}' file

Or one newline:

sed -n '/TODO/{:a;N;/\n\n$/s//\n/p;Ta}' file
like image 42
potong Avatar answered Sep 30 '22 00:09

potong