排除域名与全局域名匹配的电子邮件

时间:2012-10-29 10:28:28

标签: sed awk grep cut tr

全局域名为“* @”选项,当电子邮件与其中一个全局域名匹配时,我需要将其从列表中排除。

示例:

WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@superuser.com
WF,test@stackapps.com
WF,test@stackexchange.com

输出:

WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com

6 个答案:

答案 0 :(得分:2)

您在同一个文件中有两种类型的数据,因此最简单的处理方法是先将其划分:

<infile tee >(grep '\*@' > global) >(grep -v '\*@' > addr) > /dev/null

然后使用globaladdr中删除信息:

grep -vf <(cut -d@ -f2 global) addr

把它放在一起:

<infile tee >(grep '\*@' > global) >(grep -v '\*@' > addr) > /dev/null
cat global <(grep -vf <(cut -d@ -f2 global) addr) > outfile

outfile的内容:

WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com

使用rm global addr清理临时文件。

答案 1 :(得分:1)

你可以这样做:

grep -o "\*@.*" file.txt | sed -e 's/^/[^*]/' > global.txt
grep -vf global.txt file.txt

首先提取全局电子邮件,然后将其添加到[^*],并将结果保存到global.txt。然后将此文件用作grep的输入,其中每一行都被视为[^*]*@global.domain.com形式的正则表达式。 -v选项告诉grep只打印与该模式不匹配的行。

使用sed进行就地编辑的另一个类似选项是:

grep -o "\*@.*" file.txt | sed -e 's/^.*$/\/[^*]&\/d/' > global.sed
sed -i -f global.sed file.txt

答案 2 :(得分:1)

$ awk -F, 'NR==FNR && /\*@/{a[substr($2,3)]=1;print;next}NR!=FNR && $2 !~ /^\*/{x=$2;sub(/.*@/,"",x); if (!(x in a))print;}' OFS=, file file
WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com

答案 3 :(得分:1)

这是使用GNU awk的一种方式。像:

一样运行
awk -f script.awk file.txt{,}

script.awk的内容:

BEGIN {
    FS=","
}

FNR==NR {
    if (substr($NF,1,1) == "*") {
        array[substr($NF,2)]++
    }
    next
}

substr($NF,1,1) == "*" || !(substr($NF,index($NF,"@")) in array)

结果:

WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com

或者,这是单行:

awk -F, 'FNR==NR { if (substr($NF,1,1) == "*") array[substr($NF,2)]++; next } substr($NF,1,1) == "*" || !(substr($NF,index($NF,"@")) in array)' file.txt{,}

答案 4 :(得分:0)

一次传递文件并允许全局域与地址混合:

$ cat file
WF,*@stackoverflow.com
WF,test@superuser.com
WF,*@superuser.com
WF,test@stackapps.com
WF,test@stackexchange.com
WF,*@stackexchange.com
WF,foo@stackapps.com
$
$ awk -F'[,@]' '
   $2=="*" { glbl[$3]; print; next }
   { addrs[$3] = addrs[$3] $0 ORS }
   END {
      for (dom in addrs)
         if (!(dom in glbl))
            printf "%s",addrs[dom]
   }
' file
WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com
WF,foo@stackapps.com

或者如果你不介意2遍方法:

$ awk -F'[,@]' '(NR==FNR && $2=="*" && !glbl[$3]++) || (NR!=FNR && !($3 in glbl))' file file
WF,*@stackoverflow.com
WF,*@superuser.com
WF,*@stackexchange.com
WF,test@stackapps.com
WF,foo@stackapps.com

我知道第二个有点神秘,但它很容易被翻译成不使用默认动作和awk成语中的好练习: - )。

答案 5 :(得分:0)

这可能适合你(GNU sed):

sed '/.*\*\(@.*\)/!d;s||/[^*]\1/d|' file | sed -f - file