2014-04-29 41 views
2

我有以下的文本數據(高度簡化):簡化文本處理管線與AWK

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腳本來實現這一點?

回答

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; }' 

需要具有sed在Mac OS X(BSD)的}之前分號;沒有它,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 
+0

@dwurf:感謝 - 不知道那裏發生了什麼...... –

+0

您腳本對我的示例輸入工作良好 - 真正的數據集(在[這些說明](https://help.ubuntu.com/12.04/serverguide/kerberos-ldap.html#kerberos-ldap-openldap)中遇到)需要略微更嚴格的比賽條件。感謝真棒帖子,正是我正在尋找:) – dwurf

+0

這假設在'一些:'你有'垃圾'後。我認爲OP意味着其他數據要刪除。所以在這裏,我會去'awk'而不是'sed' – Jotne