learn_gnused icon indicating copy to clipboard operation
learn_gnused copied to clipboard

Delete text between blank lines

Open flywire opened this issue 2 years ago • 6 comments

sed can easily delete text between blank lines but gnused treats blank lines differently.

An example would be worthwhile. Two come to mind, replacing three blank lines with a single blank line and deleting a line and the following blank line (paragraph) if it contains a search string. Non-gnused:

sed 's/\n.*kill.*\n\n/\n/g' sample_text

sample_text

This is a
sample text

    kill = whatever

demonstration.

output

This is a
sample text

demonstration.

flywire avatar Jul 12 '22 01:07 flywire

I don't understand what you mean by GNU sed treats blank lines differently. By default, sed works only line by line. So, you cannot match across multiple lines unless you find a way to put them in the pattern space.

For the example you have given, I'd recommend using Perl:

perl -0777 -pe 's/\n.*kill.*\n\n/\n/g'

learnbyexample avatar Jul 12 '22 08:07 learnbyexample

I understand the gnused N command is different from other sed implementations. Certainly, using gnused this exercise requires pattern matching.

This is close but it still leaves a double line, even with regex similar to yours above:

>sed -re '/\n/{:a;N;/\n/!ba};/kill/d' sample_text
This is a
sample text


demonstration.

flywire avatar Jul 12 '22 10:07 flywire

Your command is equivalent to sed '/kill/d' since \n gets stripped from each input line (gets added back when you use N, while printing, etc).

Based on this unix.stackexchange thread:

$ sed '/^$/{:a;N;/\n$/!ba; /kill/d}' ip.txt
This is a
sample text
demonstration.

/^$/ will match an empty line and /\n$/ matches the second empty line (cannot use /^$/ here since pattern space will content from previous lines). Since the entire block is deleted, use substitute if you want to insert empty line.

Instead of all this, I'd just use awk or perl for such cases instead of sed which is just too cryptic for me with all the buffers and stuff.

learnbyexample avatar Jul 12 '22 14:07 learnbyexample

use substitute if you want to insert empty line.

Yes, that is what I was trying to work out. What does that command look like?

flywire avatar Jul 13 '22 10:07 flywire

# empty replacement string, since sed adds back the newline while printing
$ sed '/^$/{:a;N;/\n$/!ba; s/.*kill.*//}' ip.txt
This is a
sample text

demonstration.

learnbyexample avatar Jul 13 '22 14:07 learnbyexample

oops, clicked "close" issue by mistake.

learnbyexample avatar Jul 13 '22 14:07 learnbyexample