grep一个单词,如果匹配则获取括号之间的内容

时间:2015-07-23 18:13:39

标签: bash sed grep

我有很多文件,通常如下所示。

    { 
      key1:value1, 
      key2:value4 
    }, 
    { 
       key1:value1, 
       key2:value4 
    }, 
    { 
       key3:value3,
       key5:value5 
    }

我想搜索一个密钥,比如说key5。如果key5存在,那么我  我想在括号下打印所有内容。在这种情况下,它将是

    { 
       key3:value3,
       key5:value5 
    }

我不想在上下文之后和grep上下文之前做,因为括号中的键可能会有所不同。并且括号内的内容不在一行中。

3 个答案:

答案 0 :(得分:3)

您可以将gnu-awk与自定义记录分隔符一起使用:

awk -v RS='{[^}]+}' 'RT ~ /key5/ {print RT}' file
{
   key3:value3,
   key5:value5
}

RT代表RS模式匹配的文字。

另一种方法是使用gnu-grep:

grep -zoP '{[^}]*?key5[^}]*}' file
{
   key3:value3,
   key5:value5
}

编辑:您也可以使用perl

perl -0ne 'print $1  . "\n"if /({[^}]*?key5[^}]*})/' file
{
   key3:value3,
   key5:value5
}

编辑2:这是一个BSD awk解决方案:

awk -v RS='{' '/key5/{printf "%s", RS $0}' file
{
   key3:value3,
   key5:value5
}

答案 1 :(得分:1)

您已经有了答案,但是,只是为了好玩,sed解决方案:

sed -n 'H;/{/h;/}/{g;/key5/p}' file
  • 将当前行附加到 H 旧空间
  • 如果行匹配/{/,请用
  • 替换 h 旧空间的内容
  • 如果行匹配/}/ g 等等,则替换当前行。如果替换匹配/key5/,则 p 将其打印(打印保留空间中累积的所有内容,从开始{到结尾}
  • 除非明确打印(-n标志)
  • ,否则不要输出该行

与使用保留空间的任何sed脚本一样,您最好使用awk解决方案:)

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -n '/{/h;//!H;/}/!d;x;/key5/p' file

如果某行包含{,请用该行替换保留空间。否则将该行附加到保留空间。删除除}之外的所有行,在这种情况下交换到保留空间并在需要的字符串存在时打印它。

N.B。 -n开关调用类似于grep的性质,并抑制每行的正常打印。