某个目录下有两个文件a.txt和b.txt,文件格式为(ip,username),
列如:
a.txt
127.0.0.1 zhangsan
127.0.0.1 wangxiaoer
127.0.0.2 lisi
127.0.0.3 wangwu
b.txt
127.0.0.4 lixiaolu
127.0.0.1 lisi
每个文件至少100万行,请使用Linux命令完成如下工作:
1)每个文件各自的ip数
2)出现在b.txt而没有出现在a.txt的ip
3)每个user出现的次数以及每个user对应的ip数
答案,大家可以参考下:(对应把ip1,ip2分别换为a,b即可)
1):cat ip1.txt |awk -F"[\t]" '{w[$1]+=1}END{for (a in w) print a,w[a]}'|wc -l
2):diff ip1.txt ip2.txt |grep '>' |sed 's/> //g'|awk '{w[$1]+=1}END{for(a in w)print a}'
3):
cat ip1.txt ip2.txt|awk '{u[$1" "$2]+=1}END{for(i in u) print i,u[i]}'|awk 'BEGIN{print "user" "\t" "user_count" "\t" "ip_count"}{u[$2]+=$3;ip[$2]+=1}END{for(i in u)print i"\t"u[i]"\t"ip[i]}'
上面内容从网上得来。但是我个人觉得这个答案不是完全正确的,它的问题在于没有对原文件进行排序,这样在做diff操作时得到的结果不准确。
而如果加上排序的话,那么可能不能使用一条命令完成整个功能,因为我没有找到一个办法将两个排序后的内容整合在一块,换句话说,可以使用管道来重定向一个命令的结果,但是两个的怎么办?
这里要考虑sort命令可以用来排序,并且可以针对列排序。
这里需要注意的用法有:
awk中:
1 变量可以直接使用,比如这里面的w是直接用的。
2 数组的index可以为任意值,比如w[$1]。
3 循环和数组结合使用的方法:
for (a in w) print a,w[a]
4 awk中的BEGIN{}和END{}是在最初后最后只分别执行一次,而不是每行都执行。
另外,注意这里sed来处理行,跟grep相比,sed有很强功能,比如替换,这是grep无法做到的。