【问题标题】:Convert text, using sed, awk, grep使用 sed、awk、grep 转换文本
【发布时间】:2013-11-06 20:10:42
【问题描述】:

我无法解决问题。我有一个包含电子邮件地址的文本。我需要这个文件来通过井号更改地址。

例如:

bla bla bla example{at sign}gmail.com -> #######{at sign}#####.###

【问题讨论】:

  • 在此处发布示例输入数据。
  • 示例:“每封邮件只有一个标头,由字段组成。firstemail@gmail.com 每个字段都有一个名称和一个值。secondmail@gmail.com RFC 5322 指定了精确的语法 thirdmail @gmail.com。”
  • "每条消息只有一个标题,由字段组成。##########@#####.### 每个字段都有一个名称和一个值. ##########@#####.### RFC 5322 指定了精确的语法 #########@#####.### 。”跨度>
  • 文件中的所有这些文本都在一行中?

标签: linux bash sed awk grep


【解决方案1】:

你可以像这样使用 sed:

sed -r 's/(^| )[^ @]+@[^ ]+/\1#########@#####.###/g' file
Each message has exactly one header, which is structured into fields. #########@#####.### Each field has a name and a value. #########@#####.### RFC 5322 specifies the precise syntax #########@#####.### .

【讨论】:

  • 不适用于此测试echo "test my@email.com vow" | sed 's/ [^ @]+@[^ ]+/ #########@#####.###/g' 它给出了test my@email.com vow
  • 究竟什么是“同样的问题”?
  • 我用你的解决方案输出“test my@email.com vow”。
  • 对我有用,但它会删除 not@email。我最新的awk 似乎可以处理这个问题。
【解决方案2】:

这是awk 解决方案

echo "test my@email.com vow" | awk  '{split($0,a,"@");f=split(a[1],x," ");for (i=1;i<=(length($f));i++) s=s "#";$f=s}1'
test ############ vow

它保留了长度,但可能会破坏任何不是电子邮件且具有@的内容


这可能更适用于多封电子邮件:

awk '{gsub(/[^@ ]+@[[:alnum:]]+.[[:alnum:]]+/,"#########")}1' file

【讨论】:

  • 测试:输入:“my@email.com test my@email.com test my@email.com”;输出:“############ test my@email.com test my@email.com”。
  • 我看到了,测试了一个新版本
  • 当然,这对我来说很好用。你在什么操作系统上?这是我得到的:echo "my@email.com my@email.com my@email.com" | awk '{gsub(/[^@ ]+@[[:alnum:]]+.[[:alnum:]]+/,"#########")}1' ######### ######### #########
【解决方案3】:

一个丑陋的oneliner,将更改文件到位:

$ cat text
Each message has exactly one header, which is structured into fields. firstemail@gmail.com Each field has a name and a value. secondmail@gmail.com RFC 5322 specifies the precise syntax thirdmail@gmail.com
$ < text egrep -o "\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\b"  | sort -u | ( while read b ; do echo "s/$b/$(tr a-z0-9_%+-. \# <<< ${b%@*})@$(tr a-z0-9_%+- \# <<< ${b#*@})/g" ; done ) | xargs -n1 -I{} sed -i,bak {} text
$ cat text
Each message has exactly one header, which is structured into fields. ##########@#####.### Each field has a name and a value. ##########@#####.### RFC 5322 specifies the precise syntax #########@#####.###

我从here 获取了电子邮件正则表达式。我还假设电子邮件左侧的一个点也应该被混淆:first.name@gmail.com --&gt; #########@#####.###

【讨论】:

    【解决方案4】:

    问题是您如何知道您是否有电子邮件地址。您可以假设一个模式,例如/[\.\w]+@[\.\w]+\.\w+/,但这可能包括电子邮件以外的其他内容。你想保持长度,还是一般替换它:

    • david@foo.com => #####@###.###
    • robert.brown@buffy.fu => ############@#####.##

    或

    • david@foo.com => #################@##################.###
    • robert.brown@buffy.fu => #################@##################.###

    后者可以与sed 一起使用s/[\.\w]+@[\.\w]+\.\w+/#################@##################.###/。请注意,sed 因系统而异——尤其是关于它可以接受哪些类型的正则表达式语法。 sed 至少可以使用三种不同的正则表达式:Obsolete(或 RE Classic)、Modern(包括一些扩展)和 Extended(如 Perl 和 Python)


    在 Mac OS X - Mavericks 上测试

    sed -E 's/\s*[[:alnum:]\.]+@[[:alnum:]\.]+\.[[:alnum:]]+\s*/######@#####.###/g' rfc-5322.txt
    

    我在 RFC-5322 上对此进行了测试

    【讨论】:

    • 我想保持长度。关于三种正则表达式我听到的第一种。我刚开始研究这个。
    • 保持长度会使这个问题变得更加困难。另外,如果您的目的是混淆信息,那么保持长度意味着您甚至可以区分电子邮件地址,甚至是混淆的。将它们全部设置为相同的长度意味着您完全隐藏了该信息。
    • 谢谢。我愿意倾听并学习另一种解决方案。谢谢。
    • 可能我有什么不懂的,上面的例子,我就撤了原文。嗯?
    • 为了让它更复杂一些,请在此处查看电子邮件正则表达式:regular-expressions.info/email.html
    猜你喜欢
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2022-11-30
    相关资源
    最近更新 更多