我有很多文件,通常如下所示。
{
key1:value1,
key2:value4
},
{
key1:value1,
key2:value4
},
{
key3:value3,
key5:value5
}
我想搜索一个密钥,比如说key5。如果key5存在,那么我 我想在括号下打印所有内容。在这种情况下,它将是
{
key3:value3,
key5:value5
}
我不想在上下文之后和grep上下文之前做,因为括号中的键可能会有所不同。并且括号内的内容不在一行中。
答案 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
/{/
,请用/}/
, g 等等,则替换当前行。如果替换匹配/key5/
,则 p 将其打印(打印保留空间中累积的所有内容,从开始{
到结尾}
-n
标志)与使用保留空间的任何sed
脚本一样,您最好使用awk
解决方案:)
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -n '/{/h;//!H;/}/!d;x;/key5/p' file
如果某行包含{
,请用该行替换保留空间。否则将该行附加到保留空间。删除除}
之外的所有行,在这种情况下交换到保留空间并在需要的字符串存在时打印它。
N.B。 -n
开关调用类似于grep的性质,并抑制每行的正常打印。