funfun
funfun

Reputation: 39

how to delete lines connected with "+" signs with sed

In this example, "+" sign means it connects the previous line and the current line. So I like to delete a specific group of lines that are connected by "+". For example, I'd like to remove from 1st line to 4th line(.groupA ~ + G H I). Please help me on how to do it with sed.

Upvotes: 1

Views: 105

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207435

IMHO this is more readily done with awk, but kindly just ignore if that is not an option for you.

So, every time I see a line starting with .groupA, I set a flag d to say I am deleting, and then skip to the next line. If I see a line starting with a + and I am currently deleting, I skip to the next line. If I see anything else, I change the flag to say I am no longer deleting and print the line:

awk '/^\.groupA/  {d=1; next}
     /^+/ && d==1 {next} 
                  {d=0; print}' file

Sample Output

** Example **
abcdef ghijkl
.groupB abc def
+ JKL
+ MNO
+ GHI
opqrst vwxyz

You can cast it as a one-liner like this:

awk '/^\.groupA/{d=1; next} d==1 && /^+/ {next} {d=0;print}' file

Upvotes: 1

randomir
randomir

Reputation: 18687

To delete lines starting with .groupA and all consecutive +-prefixed lines, one easy to understand approach is:

sed '/\.groupA/,/^[^+]/ { /\.groupA/d; /\.groupA/!{/^\+/d} }' file

We first select everything between .groupA and the first non +-prefixed line (inclusive), then for that selection of lines, we delete the first line (containing .groupA), and of the remaining lines, we delete all with + prefix.

Note you need to escape regex metacharacters (like . and +) if you want to match them literally.


A little bit more advanced, but more elegant (only one use of starting block pattern) approach uses a loop to skip the first line of the matched block, and all the following lines that start with +:

sed -n '/\.groupA/ { :a; n; s/^\+//; ta }; p' file

Upvotes: 1

Related Questions