sed - 删除匹配模式之前和之后的n行

时间:2015-03-27 09:13:14

标签: linux sed

删除" n"匹配模式后面的行很容易使用:

IFM_MOUNT="/opt/insiteone/fuse-mount2/ifm"
sed -i "\|$IFM_MOUNT|,+6 d" smb.conf (deletes lines matching and next 6 lines)

但我的问题是,我希望删除匹配模式之前的2行。

如何实现? 我将调用该命令的文件是Samba配置文件,如下所示:

[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

2 个答案:

答案 0 :(得分:3)

正如我评论的那样,如果格式是固定的(数据块之间的空行),这一行就可以完成这项任务:

awk -v RS="" '!/PATTERN/' input

如果不是这种情况,你可以试试这个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

测试

  • ifm简化为PATTERN
  • “数据块”之间没有空行
  • 遵循您的规则:删除行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
    

修改

使用shell变量中的模式:

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

答案 1 :(得分:0)

您使用以下sed命令:

sed -r ':a;N;s~([^\n]*\n){2}[^\n]*'"$search"'\n~~;ba' file

该命令基本上作为循环工作。 :a标记循环开始处的标签。 N读取下一行输入并将其附加到模式缓冲区。 s~([^\n]+\n){2}PATTERN\n~~将删除模式,并在其前面删除两行。请注意,我使用~作为分隔符,因为输入数据包含“标准”分隔符/ba将分支回到循环的开头。在输入结束时,修改后的文件将被打印$p

顺便说一句,只需将搜索模式中的2更改为您想要的任何内容,即可将模式更改为任意数量的前一行。