SED 或 AWK 提取字符串到行尾只留下找到的第一个结果

SED or AWK extract between string to end of line leave only first result found

尝试编写一个电子邮件处理器从电子邮件中提取一些数据(基于dovecot/postfix),因此文件位于

/home/moderator/Maildir/cur/1619183102.V97eI6001a560M865218.example.com:2,S

假设

/home/moderator/Maildir/cur/file

电子邮件文件文本包含文本和 HTML

Subject: New user
New user created 
User name:Billy Jean
<html><head><title>New user</title>
</head>
<body>
<p>New user created</p>
User name:Billy Jean<br>
</body>

任务是准确提取

之间的用户名Billy Jean
User name:

和行尾

但只保留第一个实例以避免重复(忽略 HTML 行 User name:Billy Jean<br>

已经测试了 Whosebug 的一些变体,例如

awk '/^User name:/{print $NF}' /home/moderator/Maildir/cur/file

但它没有给出必要的结果,与我的问题不符。

感谢任何尝试的想法,

使用您显示的示例,请尝试以下 awk 代码。查找要搜索的字符串,并在打印所需值后在其首次存在时退出。

awk -F':' '/^User name:/{print $NF;exit}' /home/moderator/Maildir/cur/file

奖金解决方案: 以防您的 awk 程序有更多的事情要处理而我们无法摆脱不做所有事情的程序,然后使用 print 添加一个简单的条件检查,以便它只打印第一次出现的字符串。

awk -F':' '/^User name:/ && ++count==1{print $NF} {your rest of code here....}' /home/moderator/Maildir/cur/file

另一个使用 matchsubstr:

$ awk 'match([=10=],/^User name: */){print substr([=10=],RSTART+RLENGTH);exit}' file

输出:

Billy Jean

解释:

$ awk 'match([=12=],/^User name: */) {   # regex to match
    print substr([=12=],RSTART+RLENGTH)  # print everything after match
    exit                             # exit after first match (or nextfile)
}' file

此外,如果未设置 User name:,您可能应该在内容部分之前考虑一些退出机制,示例中为 /^<html>/{exit}

sed '/^User name:/!d;s///;q' file
awk 'sub(/^User name:/,"") {print; exit}' file

sed -n '/^</q;/^User name:/!d;s///;p;q' file
awk 'f = sub(/^User name:/,""); f || /^</ {exit}' file