搜索模式x(并打印该行),在后续行中使用patten y grep行直到下一个空行

时间:2016-06-22 14:53:43

标签: bash awk sed grep

示例文字:

dn: uid=test,ou=domain.eu,o=org
uid: test
mailEquivalentAddress: john@domain.eu
mailEquivalentAddress: johndoe@domain.eu

dn: uid=test2,ou=domain.eu,o=org
uid: test2

dn: uid=test3,ou=domain.eu,o=org
uid: test3

因此,并非所有条目都有mailEquivalentAddress,可能有多个mailEquivalentAddress。

我希望获得具有一个或多个mailEquivalentAddresses的所有条目。 要解释标题:grep表示以dn开头的所有行:以及所有后续行,但只有当有一个或多个mailEquivalentAddress时,才停在下一个空行。

所以我想要的输出是:

dn: uid=test,ou=domain.eu,o=org
uid: test
mailEquivalentAddress: john@domain.eu
mailEquivalentAddress: johndoe@domain.eu

使用可变数量的mailEquivalentAddresses。

3 个答案:

答案 0 :(得分:4)

我会使用awk

awk '$1 ~ /^dn:/{for(i=1;i<=NF;i++){if($i ~ /^mailEquivalentAddress:/){print; break}}}' RS='' file
  • RS=''记录分隔符的特殊值。它告诉awk通过空行(段落)将文件拆分为记录,并将字段分隔符设置为换行符。

  • $1 ~ /^dn:/检查段落中的第一行是否以dn:开头

  • 程序本身是一个循环,通过所有字段检查字段是否以单词mailEquivalentAddress:开头。如果找到这样的字段awk将打印段落。

答案 1 :(得分:3)

{p> file

中的示例文字
dn: uid=test,ou=domain.eu,o=org
uid: test
mailEquivalentAddress: john@domain.eu
mailEquivalentAddress: johndoe@domain.eu

dn: uid=test2,ou=domain.eu,o=org
uid: test2

dn: uid=test3,ou=domain.eu,o=org
uid: test3

dn: uid=test4,ou=domain.eu,o=org
uid: test4
mailEquivalentAddress: jason@bourne.eu
mailEquivalentAddress: matt@damon.eu

<强>脚本

awk 'BEGIN{RS="";ORS="\n\n"}/^dn:.*\nuid:.*\nmailEquivalentAddress: [[:alnum:]]+/'  file

<强>输出

dn: uid=test,ou=domain.eu,o=org
uid: test
mailEquivalentAddress: john@domain.eu
mailEquivalentAddress: johndoe@domain.eu

dn: uid=test4,ou=domain.eu,o=org
uid: test4
mailEquivalentAddress: jason@bourne.eu
mailEquivalentAddress: matt@damon.eu

备注:

  1. 我认为mailEquivalentAddress:可以被视为关键。
  2. 从你给出的输入中可以看出,每条记录之间都有一个空行,所以我保留了记录分隔符RS=""
  3. 我们通过/^dn:.*\nuid:.*\nmailEquivalentAddress: [[:alnum:]]+/查看记录
    • 检查dn(在开始时)和uid键是否强制存在于记录中。
    • 表示以mailequivalentAddress:开头的行,如果是,我们可以确定它是一个键。然后,我们确保[[:alnum:]]+非空,如果是,我们打印记录。

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed -n '/^dn:/{:a;$!{N;/\n$/!ba};/mailEquivalentAddress:/p}' file

如果一行开始dn:获取更多行,直到空行或文件结尾。测试这些行是否存在mailEquivalentAddress:并且如果找到则打印它们。