buydadip
buydadip

Reputation: 9407

sed - delete all lines that contain one pattern but not another

I want to delete all lines in a file that contain one pattern, but not another.

For example, if I have this file:

hello people foo
hello world bar
hello something
blah blah blah

I want to delete all lines that contain hello, but not world, so that my file looks like this:

hello world bar
blah blah blah

I tried the following:

sed -n '/hello/p' file | sed -i '/world/!d'

But I get the error message -i may not be used with stdin

Upvotes: 1

Views: 2572

Answers (6)

buydadip
buydadip

Reputation: 9407

After playing a round a bit, I was able to procure one script implementing sed, which worked for me:

file=$1
patt=$(sed -n '/world/p' $file)
sed -n "/hello/!p;/$patt/p" $file

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203209

Just use awk to keep the logic simply as-stated:

$ awk '/hello/ && !/world/{next} 1' file
hello world bar
blah blah blah

Upvotes: 1

repzero
repzero

Reputation: 8412

sed -i.bak '/hello/{/world/!d}

this answer is different since an extension is provided to -i.

I the thread below should be useful

sed command with -i option failing on Mac, but works on Linux

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 246744

A single sed invocation:

sed -n '/hello/ {/world/d; p}' file

For lines matching /hello/, if it also matches /world/ delete, else print

Upvotes: 5

Kent
Kent

Reputation: 195029

an awk alternative:

awk '!/hello/ ||/world/' file

Upvotes: 4

iruvar
iruvar

Reputation: 23374

This should work

sed  -i '/hello/{/world/!d}' file

Upvotes: 6

Related Questions