2013-01-14 32 views

回答

1

如果你的數據是,你真的表現爲簡單的,你可以用awk sub()函數來得到你不想要的東西搭,即

awk '{ 
     # inside the implied awk process-all-lines-of-input-loop 
     email=$0 
     if (email ~ /<\.*>/) { 
     sub(/^.*</,"", email) 
     sub(/>.*$/,"", email) 
     } 
     else { email=$2 } 
     printf("%s\t%s\n", $1, email) 
     }' mailFile > newMailFile 

cat newMailFile 
17  17 [email protected] 
9  [email protected] 
8  [email protected] 

請注意,我們複製了整條生產線( $0),變量email,然後刪除從左邊開始的所有字符,直到第一個< char,然後在email變量的末尾刪除任何東西,從關閉> char開始。請注意,電子郵件地址對於角落案例的解析可能相當複雜,所以有可能這種技術可能會遺漏某些情況,但鑑於其簡單性,它應該足夠好。

此外,如果您不習慣awk和shell編程,請注意,你不能用相同的輸出文件名覆蓋輸入文件」不要試圖像awk '....' file > file,這將從根本上消滅file

的printf的是打印數據看中方式,\t爲您提供了2個字段之間的製表字符。 你也可以用print $1 "\t" email做到這一點更簡單。

IHTH。

+0

在現實世界中,您可能還會遇到遺留格式'[email protected](名字姓氏)'。 – tripleee

+0

@tripleee:好的一點,我已經更新了我的代碼以解釋可能的情況。感謝第二套眼睛。祝你們好運! – shellter

0
$ cat stack 
17 [email protected] 
9 Limited <[email protected]> 
8 "Fishing Forum" <[email protected]> 

$ cat stack | awk '{ print $1" "$NF }' | sed 's/<//g; s/>//g' 
17 [email protected] 
9 [email protected] 
8 [email protected] 

如果你想輸出的第一列之間的tab,請使用類似以下內容:

$ cat stack | awk '{ print $1"\t"$NF }' | sed 's/<//g; s/>//g' 
17 [email protected] 
9 [email protected] 
8 [email protected] 

如果你只需要電子郵件地址:

$ cat stack | awk '{ print $NF }' | sed 's/<//g; s/>//g' 
[email protected] 
[email protected] 
[email protected] 

FYI:NF給你的字段的總數在一行

+0

您不需要將awk傳入sed:'awk'{gsub(/ [<>] /,「」,$ NF);打印$ 1,$ NF}'' –

2

爲了處理所有可能的電子郵件選項(請參閱tripleee評論),您需要將電子郵件與正則表達式匹配:

gawk --re-interval '{match($0,/[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Z]{2,4}/);print $1 " " substr($0,RSTART,RLENGTH)}' 

它取自這裏的正則表達式:http://www.regular-expressions.info/email.html。您應該對其進行測試,以驗證它是否涵蓋所有法律電子郵件。

+0

如果您使用的是regular-expressions.info,我認爲它確實沒有。 – tripleee

+0

+1爲解決方案,但使用字符類[[:alpha:]]而不是顯式範圍,如[A-Za-z],因爲後者不匹配所有語言環境中的所有字母:'/ [[:alnum: ] ._%+ - ] + @ [[:alnum:] .-] + \ [[:阿爾法:]] {2,4} /'。請注意,由於[A-Z]顯然是錯誤的,因此我將[A-Z]更改爲[[:alpha:]]而不是[[:upper:]]。我懷疑還有其他問題,但它可能足夠好。 –

相關問題