全局域名为“* @”选项,当电子邮件与其中一个全局域名匹配时,我需要将其从列表中排除。
示例:
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
答案 0 :(得分:2)
您在同一个文件中有两种类型的数据,因此最简单的处理方法是先将其划分:
<infile tee >(grep '\*@' > global) >(grep -v '\*@' > addr) > /dev/null
然后使用global
从addr
中删除信息:
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