使用awk简化文本处理管道

时间:2014-04-29 00:23:33

标签: awk sed

我有以下文本数据(高度简化):

dn: cn=config
objectClass: olcGlobal
cn: config
some: properties

dn: cn={0}kerberos,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: {0}kerberos
some: properties
some: junk
some: more junk

dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
some: properties

所需的输出是:

dn: cn=kerberos,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: kerberos
some: properties

我已经编写了以下shell管道来实现这个目标:

awk -vRS= -vFS="\n" '/kerberos/{print $0}' /tmp/input.txt | \
    sed 's/{0}kerberos/kerberos/' | \
    sed '/some: junk/,$d'

这很好用,但我觉得这是'作弊'混合awk和sed。如何使用单个awk脚本实现此功能?

1 个答案:

答案 0 :(得分:3)

显然,您只需要一个sed命令,而不是两个:

sed -e 's/{0}kerberos/kerberos/' -e '/some: junk/,$d'

除非你坚持使用C shell,否则行末端的反斜杠是不必要的。

您可以在一个sed命令中完成所有操作:

sed -n -e '/kerberos/,/^$/{
        s/{0}kerberos/kerberos/
        /some: junk/,$d; p;}' 
s///替换后,

可以用分号展平成一行。

sed -n -e '/kerberos/,/^$/{ s/{0}kerberos/kerberos/; /some: junk/,$d; p; }' 

在Mac OS X(BSD)上}需要sed之前的分号;没有它,GNU sed很高兴。

您也可以在awk中完成所有操作:

awk '/kerberos/,/^$/ { sub(/\{0\}kerberos/,"kerberos");
                       if ($0 ~ /^some:/ && some++ > 0) next;
                       if ($0 != "") print
                     }' input.txt

,对于输入数据,产生:

dn: cn=kerberos,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: kerberos
some: properties