16

Ok

I know that this is trivial question but: How can i remove lines from files that are between two known patterns/words:

pattern1
garbage
pattern2

to obtain:

pattern1
pattern2

And does anyone known good(simple written!) resources for studying sed?? With many clear examples?

1

6 Answers 6

20
sed -n '/pattern1/{p; :a; N; /pattern2/!ba; s/.*\n//}; p' inputfile 

Explanation:

/pattern1/{ # if pattern1 is found p # print it :a # loop N # and accumulate lines /pattern2/!ba # until pattern2 is found s/.*\n// # delete the part before pattern2 } p # print the line (it's either pattern2 or it's outside the block) 

Edit:

Some versions of sed have to be spoon-fed:

sed -n -e '/pattern1/{' -e 'p' -e ':a' -e 'N' -e '/pattern2/!ba' -e 's/.*\n//' -e '}' -e 'p' inputfile 
Sign up to request clarification or add additional context in comments.

8 Comments

it gives me sed: -e expression #1, char 58: Unknown option to 's'. My sed version is 3.02
@Dennis: Oh, version from edit is doing the right thing. Thanks once more !
Or with less black magic sed '/pattern1/,/pattern2/{/pattern1/b;/pattern2/b;d}' inputfile :)
@pooh: Your first one doesn't work with this test data (lines with "xxx" should not be printed, everything else should): echo -e 'aaa\npattern1\ncccxxx\ndddxxx \npattern2\nfff\nggg\npattern1\nAAAxxx\nBBBxxx \nCCCxxx\nDDDxxx\npattern2\nEEE\nFFF'
@Dennis Williamson: Ah, true:) Tested on one line contents!
|
17

This will work for both GNU and BSD sed:

sed '/pattern1/,/pattern2/{//!d;}' file 

2 Comments

If anybody else uses this with BSD sed (i.e. Mac OSX), and you get an error extra characters at the end of d command, simply add ; after the d like this: sed '/pattern1/,/pattern2/{//!d;}' file
how do you do this inclusive of the patterns?
5

This is easily done with awk:

BEGIN { doPrint = 1; } /pattern1/ { doPrint = 0; print $0; } /pattern2/ { doPrint = 1; } { if (doPrint) print $0; } 

I've found the sed info is fairly easy reading, with many examples. Same thing for awk.

Comments

4
awk '/pattern1/{g=1;next}/pattern2/{g=0;next}g' file 

Comments

3

This sed code will work as well:

sed '/PATTERN1/,/PATTERN2/d' FILE 

1 Comment

Although not as OP wanted, this works well as the inclusive version of the answer by @potong
0

You may also use the Unix text editor ed:

echo ' pattern1 garbage pattern2 ' > test.txt cat <<-'EOF' | sed -e 's/^ *//' -e 's/ *$//' | ed -s test.txt &>/dev/null H /pattern1/+1,/pattern2/-1d wq EOF 

For more information see: Editing files with the ed text editor from scripts

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.