我编写了一个程序,它从一个目录及其所有子目录中获取电子邮件列表,并计算发生的每封电子邮件。
我现在要做的是从该列表中获取并显示出现最多的域列表。
shopt -s globstar
PUNISHED=$1
VENOM=$2
echo >> topemails.txt
echo >> emails_top_domains.txt
for files in ./$(VENOM)/**/*; do
if [ -f "${files}" ] ; then
< "$files" tr '[[:upper:]]' '[[:lower:]]'
| grep -Eiorh '([[:alnum:]_.-]+@[[:alnum:]_.-]+?.[[:alpha:].]{2,4})' 2> /dev/null
| sort -nr
| uniq -c > topemails.txt
fi
done
< topemails.txt
| grep -Eiorh '(@[[:alnum:].-]+?.[[:alpha:].]{2,4})' 2> /dev/null
| tr -d "@"
| uniq -u > emails_top_domains.txt
echo "The top "${PUNISHED}" emails are"
head -$PUNISHED topemails.txt
echo "The top domains are"
head -$PUNISHED emails_top_domains.txt
我一直遇到的一个问题是,我得到的域在我的列表中重复出现,如果我使用 uniq -u,这不应该发生,对吧?
我的代码是这样工作的,我调用脚本,有 N 个变量和一个目录。
./myscript 10/home/alabasterTenRing/
它将打印在该域及其子目录中的文件中出现最多的电子邮件列表,然后打印出现最多的域列表,并将这些域名放入文件中。
但是,以下是出现的域名列表:
mail.goo.ne.jp
gmail.com
jlt3.sipsolutions.net
freewrt.org
yahoo.com
in.ibm.com
gmail.com
arm.com
arndb.de
gmail.com
Gmail不应该重复两次,更不用说三次了。明明我在这里做错了什么,我哪里做错了?
在传递给uniq -u
之前,您没有对输入进行排序。从人uniq
做:
过滤相邻的匹配行。.
如果匹配的行不相邻,uniq 将再次打印它们。
对于您的情况,您可以使用sort -u
.但sort | uniq -u
也会起作用。
笔记:
- 您正在每个循环中重新创建文件
topemails.txt
,因为您使用>
.很可能您想要追加到文件中。 for files.. if -f
看起来可以用find ./$(VENOM) -type f
和while read
代替,或者只用find ./(VENOM) -type f | xargs cat | tr '[:upper:]' '[:lower:]' ....
tr
课前和课后不需要[
]
。因为它们在输入和替换中都指定了,所以tr替换了[
的[
和]
的]
,它们被解释为普通字符,而不是特殊处理。