sed command to grep multiple pattern present in single line and delete that line

here is what i want to achieve.. i have a file with below contents

cat fileName
blah blah blah
.
.DROP this
REJECT that
.
 --sport 7800 -j REJECT --reject-with icmp-port-unreachable
 --dport 7800 -j REJECT --reject-with icmp-port-unreachable
.
.
.
more blah blah blah
--dport 3306 -j DROP
.
.
.
blah blah blah
--dport 5070 -j REJECT --reject-with icmp-
port- 5070 -j REJECT --reject-with icmp-port-unreachable
--dport 5070 -j DROP
 5070 -j DROP
.
.blah blah

Now i just want to remove which ever lines which has below things
1> If the line has 7800 and REJECT string
2> If the line has 3306 and DROP string
3> If the line has 5070 and REJECT or DROP String

i tried below things so far

sed -i '/REJECT\|DROP/d' fileName

but this will remove all DROP and REJECT commands in the file

i also tried below command

sed -i '/*7800*REJECT*\|*5070*DROP\|REJECT*\|*3306*DROP*/d' fileName

its removing but its failing for 3306 and 5070 cum DROP.

any help on this is appreciated.

With awk

awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' fileName
blah blah blah
.
.DROP this
REJECT that
.
.
.
.
more blah blah blah
.
.
.
blah blah blah
.
.blah blah

Is there any way to use this without any redirection to file.. the above command will just display it.. i want it to be saved in the file.

Yes, like this

command bla bla | awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' >newfile

Just add a pipe | and then the awk command after the command that gives you the output.

If its in a file and you like to store this to a new file, do like this

awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' fileName >newfile

Do not do like this, (no need to cat , since awk read file directly)

cat fileName | awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' >newfile

After piping , the awk command will just thow output on console... it doesnt do any file write operation.
i have a file - fileName after executing the command it should just remove the patterned lines from this file and save it.. and not to display anything on console...

What command do you have that gives you the output?`

Test this

command bla bla | awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/) {print | "tee /tmp/newfile"}'

not command output.. its just a file with few contents where i want to remove the pattern lines from it.

Then this should do it:

awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' fileName >newfile

No output to console , only to a new file named newfile

okay... but as i said before i dont want to redirect to new file... if i redirect to same file the content will be lost.

i just want a command which after executing it, it should remove the lines from that file. Now for the above process i need to execute two command one for redirecting to new file and again copy it to old file or rename the file.

awk '!(/7800/ &&  /REJECT/ || /3306/ && /DROP/ || /5070/ && /REJECT|DROP/)' fileName >newfile
rm fileName 
mv newfile fileName 
1 Like
sed -i '/7800.*REJECT/d; /3306.*DROP/d; /5070.*REJECT/d; /5070.*DROP/d;' fileName
1 Like

Thanks Jotne and MadeinGermany... :slight_smile:

/5070.*REJECT/d; /5070.*DROP/d;

This regex /5070.*(REJECT|DROP)/ seems to work on awk , but not sed , any idea.

Edit
Shorten my awk

awk '!(/7800.*REJECT/ || /3306.*DROP/ || /5070.*(REJECT|DROP)/)' fileName

PS Using regex this way 7800 needs to come before REJECT . It will not work the other way around.

GNU sed takes /5070.*\(REJECT\|DROP\)/

Ahh, thanks

So then your line could be shorten to:

sed -i '/7800.*REJECT/d; /3306.*DROP/d; /5070.*\(REJECT|DROP\)/d;' fileName