实战演练awk

众所周知,awk、sed是相对高阶的Linux命令,是处理数据的神兵利器。另外awk不仅仅是一个命令,它本身的语法也是一门编程语言。

学习awk有时候倒不是有多难,只是各种细节,经常忘,每次用起来的时候又要重新在浩瀚的互联网上搜索一番。着实费力,本文用一些实战演练来帮你学习awk,建议收藏。用的时候可以速查一下。

数据集

首先为了方便演练,我们需要一个公开的数据集,可以去这个网站:https://grouplens.org/datasets/movielens/ 寻找电影评分相关的数据。

你也可以直接复制如下链接,来直接数据集的压缩包。https://files.grouplens.org/datasets/movielens/ml-25m.zip

rating.csv

rating.csv数据集中一个csv文件,记录了用户给电影评分相关的数据,它有4列,如下:

userId,movieId,rating,timestamp 1,296,5.0,1147880044 1,306,3.5,1147868817 1,307,5.0,1147868828 1,665,5.0,1147878820 1,899,3.5,1147868510 1,1088,4.0,1147868495 1,1175,3.5,1147868826 1,1217,3.5,1147878326 1,1237,5.0,1147868839

首先可以预处理去掉第一行(列名)

sed -i '1d' ratings.csv

聚合

计算总评分

awk -F ',' '{sum += $3} END {print sum}' ratings.csv 

awk的列序号是从1计数的,因为0表示这一整行。评分(rating)是第三列,所以加$3

计算平均分

awk -F ',' '{sum += $3} END {print sum/NR}' ratings.csv

统计每个用户给多少部电影评过分

awk -F',' '{x[$1]++} END{for (i in x) printf("%s,%s\n", i,x[i])}' ratings.csv
awk -F',' '{x[$1]++} END{for (i in x) print i","x[i]}' ratings.csv

print i","x[i] 可以替换成 printf("%s,%s\n", i, x[i])

计算每个用户评分的平均分

awk -F',' '{x[$1]++; y[$1]+=$3} END{for (i in x) print i","y[i]/x[i]}' ratings.csv

生成每个用户打过分的电影列表

userId后面使用: movId之间用,

awk -F',' '{x[$1][$2]=0} END{for(i in x) {printf("%s:",i); for(j in x[i]) printf("%s,",j); print ""}}' ratings.csv

107845:25,32,36,62,95,112,141,260,494,608,628,637,648,653,733,736,762,786,788,802,

上面这个语法用到了awk的二维数组,有些awk的命令可能不支持(比如Mac上的awk),还可以这样写:

awk -F',' '{x[$1] = x[$1]""$2","} END {for (i in x) print i":"x[i]}' ratings.csv

字符串的拼接不用直接用+,不然会按数字处理。字符串的拼接用a = a""b

如果想去掉末尾的逗号。

awk -F',' '{if (x[$1] != "") x[$1] = x[$1]","$2; else x[$1] = ""$2;} END {for (i in x) print i":"x[i]}' ratings.csv

生成每个用户打过分的电影列表含评分

格式如下:

userid:movId,rating;movid,rating;

awk -F',' '{x[$1] = x[$1]""$2","$3";"} END {for (i in x) print i":"x[i]}' ratings.csv

可以将上面生成文件保存成new_rating.csv。继续用来演示数据拆分

拆分

把new_rating拆分成单行

格式如下:

userId,movId,rating

awk -F'[:;]' '{for(i = 2; i < NF; i++) print $1","$i}' new_rating.csv

133419,81562,3.0 133419,96488,4.0 133419,5952,3.5 133419,34405,3.5 133419,6187,3.5 133419,4226,4.0 133419,33166,4.5 133419,3977,3.0 133419,6539,4.0 133419,3897,4.0

把new_rating拆分成单行

同时修改分隔符为TAB

userId\tmovId\trating

两次分割实现:

awk -F'[:;]' '{for(i = 2; i < NF; i++) {split($i, x, ","); print $1"\t"x[1]"\t"x[2] }}' new_rating.csv

一次分割实现

awk -F'[:;,]' '{for(i = 2; i < NF; i+=2) print $1"\t"$i"\t"$(i+1)}' new_rating.csv

关联

将电影ID替换成电影名

我们的数据集中还有一个文件是 movies.csv,里面有电影的信息:

movieId,title,genres 1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fan>tasy 2,Jumanji (1995),Adventure|Children|Fantasy 3,Grumpier Old Men (1995),Comedy|Romance 4,Waiting to Exhale (1995),Comedy|Drama|Romance 5,Father of the Bride Part II (1995),Comedy 6,Heat (1995),Action|Crime|Thriller 7,Sabrina (1995),Comedy|Romance 8,Tom and Huck (1995),Adventure|Children 9,Sudden Death (1995),Action

这需要awk一次处理两个文件

awk -F',' 'BEGIN {FS=","; while(getline<"movies.csv") a[$1]=$2} {$2=a[$2]; OFS=",";print $0}' ratings.csv

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...