![在 awk 中,如何在模式搜索打印前添加字符串](https://linux22.com/image/177411/%E5%9C%A8%20awk%20%E4%B8%AD%EF%BC%8C%E5%A6%82%E4%BD%95%E5%9C%A8%E6%A8%A1%E5%BC%8F%E6%90%9C%E7%B4%A2%E6%89%93%E5%8D%B0%E5%89%8D%E6%B7%BB%E5%8A%A0%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
抱歉,这个简单的问题,我似乎找不到答案。我们有一个包含大量电子邮件的文件。
<To: [email protected]>
<Cc: [email protected]>
<From: [email protected]>
hello person here is random text
等等,重复 20 多封电子邮件
老师希望学生在 awk 中打印包含电子邮件的行,同时在开头添加“email =”。他的提示是使用 To: From: 和 Cc: 作为模式搜索。他的理想输出是
email = [email protected]
email = [email protected]
email = [email protected]
但他也会采取
email = <To: [email protected]>
email = <Cc: [email protected]>
email = <From: [email protected]>
我可以让它打印后一个示例(我不知道如何从每个示例中删除垃圾字符,它们从一封电子邮件到另一封电子邮件并不一致),但是我该如何添加email =
?
到目前为止我已经
awk '/To:|From:|Cc:/ {print}' file
我还尝试了许多其他奇怪的事情,它们只给出了语法错误
谢谢你!
答案1
看起来以下内容可以满足您的需要:
awk '/To:|From:|Cc:/ {$2=substr($2,1,length($2)-1); print "email = ", $2 }' file
这一点:
{$2=substr($2,1,length($2)-1)
获取字符串中的第二个元素,类似于[email protected]>
,并删除最后一个字符>
。
然后,您只需打印所需的字符串"email = "
以及编辑后的第二个元素$2
:
print "email = ", $2
结果如下:
email = [email protected]
email = [email protected]
email = [email protected]
值得您熟悉一下打印的工作原理:https://www.gnu.org/software/gawk/manual/html_node/Print-Examples.html
答案2
命令
awk -F ":" '/To|Cc|From/{gsub(">","",$2);print "email ="$2}'
文件名
输出
email = [email protected]
email = [email protected]
email = [email protected]
Python
#!/usr/bin/python
import re
k=re.compile(r'To|Cc|From')
q=open('filename','r')
for i in q:
if re.search(k,i):
w=i.split(":")[1].replace(">","")
print "email = {0}".format(w).strip()
输出
email = [email protected]
email = [email protected]
email = [email protected]
答案3
如果目标是学习,awk
那么您可以尝试一些其他功能。这有点依赖于文件的格式,但是其他答案也是如此,所以
awk -F'>|<| ' -v OFS=" = " '/To:|From:|Cc:/{print "E-mail", $(NF-1)}' file
E-mail = [email protected]
E-mail = [email protected]
E-mail = [email protected]
首先,您可以将输入字段分隔符设置-F
为扩展正则表达式(ERE),以便它$0
在<
or>
或上中断您的输入行
-F'>|<| '
这样做会清除电子邮件地址末尾的多余字符,但留空$1
(因为前导<
),$2
包含您的过滤字段、电子邮件地址,并且末尾$3
有一个空(因为尾随)$4
>
然后偷懒,您可以将输出字段分隔符设置为=
,以便每当您打印一系列字段时,默认行为是插入=
而不仅仅是在字段之间
-v OFS=" = "
你的过滤是相同的$0
但当你打印时,因为你将输入字符串$0
分成4个(以及字段的数量,特殊awk
变量NF
=4)你想要打印$3
,这也是$(NF-1)
在这种情况下
'/To:|From:|Cc:/{print "E-mail", $(NF-1)}' file
因为您已经明确地提取了过滤字段,所以您可以通过在需要时$0
查找显式匹配来防止其他地方的意外匹配。$2
'$2=="To:"||$2=="From:"||$2=="Cc:"{......