当前位置:  开发笔记 > 编程语言 > 正文

从bash模拟"group by"的最佳方法?

如何解决《从bash模拟"groupby"的最佳方法?》经验,为你挑选了5个好方法。

假设您有一个包含IP地址的文件,每行包含一个地址:

10.0.10.1
10.0.10.1
10.0.10.3
10.0.10.2
10.0.10.1

您需要一个shell脚本,它为每个IP地址计算它在文件中出现的次数.对于先前的输入,您需要以下输出:

10.0.10.1 3
10.0.10.2 1
10.0.10.3 1

一种方法是:

cat ip_addresses |uniq |while read ip
do
    echo -n $ip" "
    grep -c $ip ip_addresses
done

然而,它真的远没有效率.

如何使用bash更有效地解决这个问题?

(有一点要补充:我知道它可以通过perl或awk解决,我对bash中的更好解决方案感兴趣,而不是那些语言.)

附加信息:

假设源文件为5GB,运行算法的机器为4GB.因此,排序不是一种有效的解决方案,也不是多次读取文件.

我喜欢类似哈希表的解决方案 - 任何人都可以对该解决方案进行改进吗?

附加信息#2:

有些人问为什么我会在bash中使用它时更加困难,例如perl.原因是在机器上我必须这样做perl不适合我.这是一个定制的linux机器,没有我习惯的大多数工具.我认为这是一个有趣的问题.

所以,请不要责怪这个问题,如果你不喜欢它就忽略它.:-)



1> Joachim Saue..:
sort ip_addresses | uniq -c

这将首先打印计数,但除此之外它应该是您想要的.


然后你可以管道"sort -nr"按降序排序,从最高到最低计数.即`sort ip_addresses | uniq -c | sort -nr`
并且`排序ip_addresses | uniq -c | sort -nr | awk'{print $ 2,$ 1}'`获取第一列中的ip地址并计入第二列.

2> 小智..:

快速而肮脏的方法如下:

cat ip_addresses | sort -n | uniq -c

如果需要使用bash中的值,可以将整个命令分配给bash变量,然后遍历结果.

PS

如果省略sort命令,则无法获得正确的结果,因为uniq仅查看连续的相同行.


uuoc,无用的猫

3> 小智..:

为了总结多个字段,基于一组现有字段,使用以下示例:(根据您的要求替换$ 1,$ 2,$ 3,$ 4)

cat file

US|A|1000|2000
US|B|1000|2000
US|C|1000|2000
UK|1|1000|2000
UK|1|1000|2000
UK|1|1000|2000

awk 'BEGIN { FS=OFS=SUBSEP="|"}{arr[$1,$2]+=$3+$4 }END {for (i in arr) print i,arr[i]}' file

US|A|3000
US|B|3000
US|C|3000
UK|1|9000



4> Diomidis Spi..:

规范解决方案是另一位受访者提到的解决方案:

sort | uniq -c

它比Perl或awk中编写的更简洁,更简洁.

您写道,您不想使用排序,因为数据的大小大于计算机的主内存大小.不要低估Unix sort命令的实现质量.Sort用于处理具有128k(即131,072字节)内存(PDP-11)的计算机上的大量数据(比如原始AT&T的计费数据).当排序遇到的数据多于预设限制(通常调整到接近机器主存储器的大小)时,它会对它在主存储器中读取的数据进行排序并将其写入临时文件.然后它使用下一个数据块重复该操作.最后,它对这些中间文件执行合并排序.这允许排序处理比机器主存储器大许多倍的数据.



5> zjor..:
cat ip_addresses | sort | uniq -c | sort -nr | awk '{print $2 " " $1}'

这个命令会给你想要的输出

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有