嗨,所以基本上我有一个' temp'我使用的文本文件有很长的各种电子邮件地址列表(一些重复)。我尝试输出的是最高频率的电子邮件地址,然后是最后的唯一电子邮件地址总数。
awk '{printf "%s %s\n", $2, $1} END {print "total "NR}' temp | sort -n | uniq -c -i
到目前为止,我得到了我想要的输出,除了,因为它没有按照最高频率排序。相反,它按字母顺序排列。
我已经被困在这几个小时了,不知道为什么。我知道我可能做错了什么,但我不确定。如果您需要更多信息并且我提供的代码不是问题,请告诉我。提前谢谢。
编辑:我也尝试过排序-nk1(输出在第一列有频率)和偶数-nk2
edit2:以下是我的“临时”的示例。文件
aol.com
netscape.net
yahoo.com
yahoo.com
adelphia.net
twcny.rr.com
charter.net
yahoo.com
编辑3:
预期产出:
33 aol.com
24 netscape.net
18 yahoo.com
5 adelphia.net
4 twcny.rr.com
3 charter.net
total 6
(不重复电子邮件,6个唯一的电子邮件地址)
答案 0 :(得分:2)
修改了示例输入以包含具有两个实例的电子邮件
$ cat ip.txt
aol.com
netscape.net
yahoo.com
yahoo.com
adelphia.net
twcny.rr.com
netscape.net
charter.net
yahoo.com
使用perl
$ perl -lne '
$c++ if !$h{$_}++;
END
{
@k = sort { $h{$b} <=> $h{$a} } keys %h;
print "$h{$_} $_" foreach (@k);
print "total ", $c;
}' ip.txt
3 yahoo.com
2 netscape.net
1 adelphia.net
1 charter.net
1 aol.com
1 twcny.rr.com
total 6
$c++ if !$h{$_}++
增量计数器用于唯一输入行,以输入行为键增加哈希值。 0
@k = sort { $h{$b} <=> $h{$a} } keys %h
获取按哈希值降序排序的键print "$h{$_} $_" foreach (@k)
根据排序的密钥@k
print "total ", $c
打印总行数
如果愿意,可以用单行写成:
perl -lne '$c++ if !$h{$_}++; END{@k = sort { $h{$b} <=> $h{$a} } keys %h; print "$h{$_} $_" foreach (@k); print "total ", $c}' ip.txt
参考: How to sort perl hash on values and order the keys correspondingly
答案 1 :(得分:2)
在Gnu awk中使用@Sundeep的数据:
$ cat program.awk
{ a[$0]++ } # count domains
END {
PROCINFO["sorted_in"]="@val_num_desc" # sort in desc order in for loop
for(i in a) { # this for in desc order
print a[i], i
j++ # count total
}
print "total", j
}
运行它:
$ awk -f program.awk ip.txt
3 yahoo.com
2 netscape.net
1 twcny.rr.com
1 aol.com
1 adelphia.net
1 charter.net
total 6
答案 2 :(得分:1)
总结了这个方便的分类工具的一些测试方法:
使用bash
(在我的情况下为v4.3.46)
sortedfile="$(sort temp)" ; countedfile="$(uniq -c <<< "$sortedfile")" ; uniquefile="$(sort -rn <<< "$countedfile")" ; totalunique="$(wc -l <<< "$uniquefile")" ; echo -e "$uniquefile\nTotal: $totalunique"
使用sh/ash/busybox
(虽然它们并非全部相同,但它们在这些测试中的工作方式相同)
time (sort temp > /tmp/sortedfile ; uniq -c /tmp/sortedfile > /tmp/countedfile ; sort -rn /tmp/countedfile > /tmp/uniquefile ; totalunique="$(cat /tmp/uniquefile | wc -l)" ; cat /tmp/uniquefile ; echo "Total: $totalunique")
使用perl
(请参阅此回答https://stackoverflow.com/a/40145395/3544399)
perl -lne '$c++ if !$h{$_}++; END{@k = sort { $h{$b} <=> $h{$a} } keys %h; print "$h{$_} $_" foreach (@k); print "Total: ", $c}' temp
使用随机生成器创建文件temp
:
55304
总地址17012
重复的地址该文件的一小部分示例如下:
24187@9674.com 29397@13000.com 18398@27118.com 23889@7053.com 24501@7413.com 9102@4788.com 16218@20729.com 991@21800.com 4718@19033.com 22504@28021.com
为了完整起见,值得一提的是表现;
perl: sh: bash:
Total: 17012 Total: 17012 Total: 17012
real 0m0.119s real 0m0.838s real 0m0.973s
user 0m0.061s user 0m0.772s user 0m0.894s
sys 0m0.027s sys 0m0.025s sys 0m0.056s
原始答案(计算总地址而非唯一地址):
tcount="$(cat temp | wc -l)" ; sort temp | uniq -c -i | sort -rn ; echo "Total: $tcount"
tcount="$(cat temp | wc -l)"
:使用行数生成变量sort temp
:为uniq uniq -c -i
:计算允许案例变化的事件sort -rn
:根据数字排序进行排序并颠倒顺序(最高位置)echo "Total: $tcount"
:显示底部的总地址示例临时文件:
john@domain.com
john@domain.com
donald@domain.com
john@domain.com
sam@domain.com
sam@domain.com
bill@domain.com
john@domain.com
larry@domain.com
sam@domain.com
larry@domain.com
larry@domain.com
john@domain.com
示例输出:
5 john@domain.com
3 sam@domain.com
3 larry@domain.com
1 donald@domain.com
1 bill@domain.com
Total: 13
修改:请参阅以下有关sort