使用awk / sed / grep从文件中的匹配模式中删除上下多行

时间:2016-10-18 04:20:36

标签: bash shell awk sed grep

我的file.txt包含:

registered 
{ 
    hostname-1 
    { 
        AAA 32; 
        BBB uuid-1;
        ip 192.168.1.1;
        host hostname-1;
        ...
        ...
        ...
    } 
} 
registered 
{
    hostname-2
    {
        AAA 31;
        BBB uuid-2;
        ip 192.168.1.2;
        host hostname-2;
        ...
        ...
        ...
    }
}
registered
{
    hostname-3
    {
        AAA 33;
        BBB uuid-3;
        ip 192.168.1.3;
        host hostname-3;
        ...
        ...
        ...
    }
}

我想根据匹配的ip删除一个完整的注册块。

E.g。如果ip是192.168.1.2那么输出应该是:

registered
{
    hostname-1
    {
        AAA 32;
        BBB uuid-1;
        ip 192.168.1.1;
        host hostname-1;
        ...
        ...
        ...
    }
}
registered
{
    hostname-3
    {
        AAA 33;
        BBB uuid-3;
        ip 192.168.1.3;
        host hostname-3;
        ...
        ...
        ...
    } 
}

我尝试了两种方法来实现这一目标,但无法使其发挥作用

1)使用grep:这不起作用。

grep -v -B6 -A6 $IP file.txt > out.txt
mv -f out.txt file.txt

2)使用awk: 如果我在下面的awk命令中给出确切的IP,那么它可以正常工作

awk '/192.168.1.2/{for(x=NR-6;x<=NR+6;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file.txt

但我想在awk命令中传递变量$ IP。它无法正常工作

awk -v pattern="${IP}" '$0 ~ pattern/{for(x=NR-6;x<=NR+6;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file.txt

非常感谢您在此找到问题的任何帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -n '/^registered/h;//!H;/^}/!b;g;/192\.168\.1\.2/!p' file

按原样提供文件。这将收集整个已注册的块并删除包含字符串192.168.1.2的那个。

答案 1 :(得分:0)

IP=192.168.1.2
awk '/'$IP'/{for(x=NR-6;x<=NR+6;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file.txt