我有以下 ldif:
dn: cn=Robert Smith,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
cn: Robert Smith
cn: Robert J Smith
cn: bob smith
sn: smith
uid: rjsmith
userpassword: rJsmitH
carlicense: HISCAR 123
homephone: 555-111-2222
mail: [email protected]
alias: [email protected]
alias: [email protected]
description: nice hair
ou: Human Resources
dn: cn=John Doe,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
cn: John Doe
cn: John Walker Doe
cn: Johnny
sn: Doe
uid: jdoe
userpassword: topsecret
carlicense: AKAHH 123
homephone: 123-458-362
mail: [email protected]
alias: [email protected]
alias: [email protected]
description: cool guy
ou: Sales
現在我正在針對它運行 awk 命令:
awk '/^mail:/ { mail = $2 }; {print mail };' ldif
預期結果是:
[email protected]
[email protected]
實際結果是:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
我真的不明白為什麼 awk 多次給出這個輸出。如果有人能向我解釋它,我將非常感激,因為我是 awk 的新手,以前沒有使用過它。我已經查閱了手冊頁和谷歌,但我想我在那裡尋找錯誤的東西...
編輯:我知道 awk 成行處理文字流。我想我的“列印”只是按照 ldif 檔案中的行數列印輸出。但我怎麼才能阻止 awk 這樣做呢?我只想將每個結果列印一次..
答案1
此條件/^mail:/
不會影響後面的所有指令,只會影響第一個指令 ( mail = $2
)。
結果,第二條指令(print mail
)被執行對於每一行。
這就是為什麼在輸出的開頭實際上有一些空白行(mail
尚未設定)。
其中任何一個都可以:
awk '/^mail:/ { { mail=$2 }; {print mail } };' ldif
awk '/^mail:/ { mail=$2; print mail };' ldif
就我個人而言,我更喜歡:
awk '/^mail:/ { print $2 }' ldif
答案2
@Dennis 提供了一個提供正確語法的解決方案,但沒有完全回答最初的問題“為什麼 awk 多次打印這一行?”
awk 在面向行的循環中運行,除了一些小的例外(例如 BEGIN 和 END)之外,它在每一行輸入上運行整個腳本。在OP的範例中,針對輸入檔的每一行執行以下偽代碼:
if LINE starts with "mail:"
set MAIL to value of second field of the input record
endif
print MAIL
輸出重複行的原因是 print 語句是外部條件語句,因此執行每一個輸入行,而不僅僅是與正規表示式相符的行。此外,由於mail
變數僅在條件語句內設置,因此舊值會一遍又一遍地重複使用,直到下一次輸入行與條件語句匹配為止。