awk 在找到另一个字符串后用新行(一次)用另一个字符串替换另一个字符串

awk replace string with another with new lines ( one time ) after finding another string

我想在第一次出现“text/html”后用 HTML 代码签名替换 ___SIGNATURE___,并且只有一个替换字符串 ___SIGNATURE___。任何剩余的 ___SIGNATURE___ 标签都应该简单地删除。

我正在处理一封电子邮件,其中 header 具有多部分边界,因此有两个 body 部分,一个带有 text/plain,另一个带有 text/html,并且___SIGNATURE___ 两者都存在标签。

所以我的脚本部分如下所示:

awk -v signature="$(cat $disclaimer_file)" '/text\/html/ {html=1;} html==1 && !swap(swap=sub(/___SIGNATURE___/, signature);}1 in.$$ > temp.mail && mv temp.mail in.$$
sed -i "s/charset=us-ascii/charset=utf-8/1;s/___SIGNATURE___//" in.$$

它有效,但这是最佳解决方案吗?

我以前用过altermime,但对我来说不是很好的解决方案。

如果无法访问示例消息,则很难预测到底什么会起作用,以及我们是否需要正确解析 MIME 结构,或者我们是否可以盲目地将消息视为文本。

在后一种情况下,重构为

awk 'NR==FNR { signature = signature ORS [=10=]; next }
    { sub(/charset="?[Uu][Ss]-[Aa][Ss][Cc][Ii][Ii]"?/, "charset=\"utf-8\"") }
    /text\/html/ { html = 1 }
    /text\/plain/ { html = 0 }
    /___SIGNATURE___/ {
        if (html && signature) {
            # substr because there is a ORS before the text
            sub(/___SIGNATURE___/, substr(signature, 2))
            signature = ""
        } else
            sub(/___SIGNATURE___/, "")
    } 1' "$disclaimer_file" "in.$$"

将避免同时调用 Awk 和 sed(以及 cat,以及相当讨厌的临时文件),其中只有 Awk 可以合理且相当舒适地完成所有工作。

如果您需要合适的 MIME 解析器,我会考虑编写一个简单的 Python 脚本。 Python 3.6+ 中的 email 库非常易于使用且灵活(但要避免使用原始 MIMEMultipart 等的 copy/pasting 旧代码;您想使用(不再非常)新 EmailMessage class).