Reputation: 12094
Deleting "n" lines following the matching pattern is easy using something like:
IFM_MOUNT="/opt/insiteone/fuse-mount2/ifm"
sed -i "\|$IFM_MOUNT|,+6 d" smb.conf (deletes lines matching and next 6 lines)
But my problem is, i wish to delete 2 lines preceeding the matching pattern as well.
How to accomplish it? The file i will be invoking the command is a Samba configuration file which looks like this:
[DCCAArchive1]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount1/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
[DCCAArchive2]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount2/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
[DCCAArchive3]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount3/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
Upvotes: 1
Views: 159
Reputation: 158100
You use the following sed
command:
sed -r ':a;N;s~([^\n]*\n){2}[^\n]*'"$search"'\n~~;ba' file
The command works basically as a loop. :a
marks a label at the loop start. N
reads the next line of input and appends it to the pattern buffer. s~([^\n]+\n){2}PATTERN\n~~
will remove the pattern and two lines before it. Note that I'm using ~
as the delimiter since the input data contains the "standard" delimiter /
. ba
will branch back to the start of the loop. On the end of input the modified file gets printed $p
.
Btw, it is simple to change the pattern to any amount of preceding lines by simply changing the 2
in the search pattern to whatever you want.
Upvotes: 0
Reputation: 195209
As I commented, if the format was fixed, (empty lines between data blocks), this line would do the job:
awk -v RS="" '!/PATTERN/' input
if it was not in this case, you can try this awk one-liner:
awk '{a[NR]=$0}/PATTERN/{for(i=NR-2;i<=NR+6;i++)d[i]=1}
END{for(i=1;i<=NR;i++)if(!d[i])print a[i]}' input
a test
ifm
as simplified PATTERN
follows your rule: remove lines hit-2 -> hit+6
kent$ cat f
fooooooooo
[DCCAArchive1]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount1/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
barrrrrrrrrrrr
[DCCAArchive2]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount2/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
kent$ awk '{a[NR]=$0}/ifm/{for(i=NR-2;i<=NR+6;i++)d[i]=1}END{for(i=1;i<=NR;i++)if(!d[i])print a[i]} ' f
fooooooooo
barrrrrrrrrrrr
use pattern from shell variable:
kent$ PAT="/fuse-mount2/ifm"
kent$ awk -v p="$PAT" '{a[NR]=$0}{if(match($0,p)>0){for(i=NR-2;i<=NR+6;i++)d[i]=1}}END{for(i=1;i<=NR;i++)if(!d[i])print a[i]} ' f
fooooooooo
[DCCAArchive1]
comment = DCCA Archive File System
path = /opt/insiteone/fuse-mount1/ifm
read only = No
public = yes
case sensitive = yes
writable = yes
create mask=0777
guest ok = Yes
barrrrrrrrrrrr
Upvotes: 3