Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using sed to delete all lines between two matching patterns

Tags:

regex

sed

I have a file something like:

# ID 1 blah blah blah blah $ description 1 blah blah # ID 2 blah $ description 2 blah blah blah blah 

How can I use a sed command to delete all lines between the # and $ line? So the result will become:

# ID 1 $ description 1 blah blah # ID 2 $ description 2 blah blah blah blah 

Can you please kindly give an explanation as well?

like image 499
Ken Avatar asked Jun 09 '11 03:06

Ken


People also ask

How do I delete a sed matching line?

To begin with, if you want to delete a line containing the keyword, you would run sed as shown below. Similarly, you could run the sed command with option -n and negated p , (! p) command. To delete lines containing multiple keywords, for example to delete lines with the keyword green or lines with keyword violet.

How do I remove a specific pattern from a Unix file?

N command reads the next line in the pattern space. d deletes the entire pattern space which contains the current and the next line. Using the substitution command s, we delete from the newline character till the end, which effective deletes the next line after the line containing the pattern Unix.

How do you use sed multiple times?

You can tell sed to carry out multiple operations by just repeating -e (or -f if your script is in a file). sed -i -e 's/a/b/g' -e 's/b/d/g' file makes both changes in the single file named file , in-place.

How do I remove all lines from a file in Linux?

Immediately after opening a file, type “gg” to move the cursor to the first line of the file, assuming it is not already there. Then type dG to delete all the lines or text in it.


2 Answers

Use this sed command to achieve that:

sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt 

Mac users (to prevent extra characters at the end of d command error) need to add semicolons before the closing brackets

sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt 

OUTPUT

# ID 1 $ description 1 blah blah # ID 2 $ description 2 blah blah blah blah 

Explanation:

  • /^#/,/^\$/ will match all the text between lines starting with # to lines starting with $. ^ is used for start of line character. $ is a special character so needs to be escaped.
  • /^#/! means do following if start of line is not #
  • /^$/! means do following if start of line is not $
  • d means delete

So overall it is first matching all the lines from ^# to ^\$ then from those matched lines finding lines that don't match ^# and don't match ^\$ and deleting them using d.

like image 70
anubhava Avatar answered Oct 10 '22 11:10

anubhava


$ cat test 1 start 2 end 3 $ sed -n '1,/start/p;/end/,$p' test 1 start end 3 $ sed '/start/,/end/d' test 1 3 
like image 29
Lri Avatar answered Oct 10 '22 09:10

Lri