Bash玩转脚本3之几个指令有趣的筛选京东评价

Bash玩转脚本3之几个指令有趣的筛选京东评价

今天在工作中遇到了一个筛选和去重问题,饶有兴致祭出Mac(为了跟公司同步,写Android一直用Win~),三两个指令搞定了去重复筛选问题,回到家中意犹未尽,决定总结一下这些年使用bash做数据筛选和去重的经验。

传送门:

Bash玩转脚本文章系列

一、数据

找数据是个头疼的问题,不过在百度过程中缺找到了一个蛮好的网站,推荐给大家http://www.datatang.com/,我从中下载了一个京东手机评价的数据,随便找了一组数据,命名为data.txt,作为本次玩耍的原始数据。

文本数据一共有多少行?

那就 wc -l一下看看。(wc是一个统计的指令,“|“是管道,简单理解就是对前面的结果继续操作)

可以看到一共有346957行,内容还是蛮多的,我们截取文本部分内容,可以看到内容的结构如图所示:

基本上所有的数据的格式都是:

  • No 编号
  • uName 名字
  • uLevel 等级
  • uAddress 地址
  • star 星级
  • commentDate 时间

  • 购买日期 时间

ok,了解了结构那现在就可以对这份数据进行我们想要的任何操作了~

二、让我想想可能需要的数据

<1> 一共有多少个评价呢?



这里可以通过使用grep 指令对某个结构内一定会出现的关键字进行抓取,然后使用wc指令统计数量,我抓取的关键字是编号——”No”。

grep "No" data.txt | wc -l

可以看到一共是有32065个评价~

<2>那32065个评价中有多少5星好评呢?



1)如果格式足够规整的话,我可以像<1>操作那样筛选,只不过关键字变成了 “star 5” ,我们可以看看结果。

grep "star 5" data.txt | wc -l

:细心的朋友可能看出了实际的指令有点点的不同,那是因为star和5间有个tab,我使用\t表示了~

2)当然,我们还有更好的方法,首先我们可以使用awk把数据进行一次格式化,然后再进行抓取和想要的操作

cat data.txt | grep "star" | awk -F "[\t]" ‘{print $2}‘

稍微解释一下,我们通过grep抓取出所有的包含star的行,然后把这些行,使用\t分隔符进行分割(awk的作用)成两列,第一列全是star,第二列则是星数,而我们把星数那一列全部print出来(这里的head -n 30只是为了方便看,只取了头30行)

万万没想到中间竟然有一条干扰数据star186102(原来有个货的用户名包含star!):

那怎么办?其实很容易,使用grep -v 剔除这一条就好了~(-v表示排除再外),完整指令如下:

cat data.txt | grep "star" | awk -F "[\t]" ‘{print $2}‘ | grep -v "star186102" | grep "5" | wc -l

结果和刚才的一样~都是25274!

<3>所有评价的平均星数是多少?



答案是还是使用awk,这个工具太强大了,我们对<2>中的awk指令做小小的修改:

cat data.txt | grep "star" | awk -F "[\t]" ‘{sum = sum + $2} END {print sum/32065}‘

我们在awk里面加入了重要的东西,那就是语句,做了一个累加的操作,可以想象到这个东西是多么的强大。(有兴趣的请自行百度awk吧!)

可以看出,>,< 4.64的评分还是蛮高的!

<4>那么谁的评论最认真呢?



怎么评判认真呢?最这里我简单的把评论最长就认为最认真~

1)首先我们要进行抓取,我选择了抓取“心得“这个关键字

cat data.txt | grep "心  得"

这里可以看到有很多很多的心得,我就不列举了。

2)使用awk对数据进行整理

cat data.txt | grep "心  得" | awk -F "心  得\t" ‘{print $2}‘

这次分割符我使用的是”心  得\t”,注意这里没有中括号,因为中括号的意思是里面的分隔符支持正则表达式,所有有没有都行。

3)我们修改一下awk的输出,使之打印出每一句评价的长度,然后这用sort进行排序

完整指令如下:

cat data.txt | grep "心  得" | awk -F "心  得\t" ‘{print length($2)"---"$2}‘ | sort -n -r | head -n 1

让我们欣赏一下最佳评价:

。。。

欣赏完了,我们解释一下,awk中的print length($2)打印出了每条心得的长度,然后加了一个- - -作为分割,因此格式就变成了:内容长度- - -内容;然后我们使用sort进行排序,-r代表倒序,-n代表按照数字排序,这样我们就得到了一个从大到小的以数字开头的列表;最后使用head -n 1取出最前的一条!

<5>这货是谁?



竟然“评价“的那么认真,那么就请出来亮个相吧!

我们通过grep语句,抓取关键字附近的内容来看看,这里我们选择的关键字就是“我发现作者在做班主任工作的时候也有很多的无奈“这一句话。

grep -A 5 -B 10 "我发现作者在做班主任工作的时候也有很多的无奈" data.txt

  • A:代表向后,后面接行数
  • B:代表向前,后面接行数

    这里我抓取了关键行前10行和后5行,看到了uName,名字叫j***1的朋友~看来他就是这个评论的作者了。

<6>喜欢用京东的人群地域分布是怎么样?



通过观察可以看到,uAddress就是注册时候填写到地域信息。虽然有部分人是没有写的,不过也不妨碍我们从技术到角度来实现这个问题。

我想到了用uniq,因为可以对数据进行去重,-c选项能够列出去重后的每一项的个数~

1)首先先挑出想要的数据

grep "uAddress" data.txt | tr "\t" " "|cut -d " " -f 2

对data.txt 进行抓取uAddress关键字,然后使用cut指令找出需要的那一列:

  • -d:后面接分隔符
  • -f:后面接第几列(和awk的一些用法其实很相似)

需要注意的是,我担心其中的分隔符有一些空行是空格,有一些却是tab制表符,所以这两个指令之间,我使用了tr指令,去把\t全部转化为空格,接着使用cut指令的时候,则可以放心的使用空格作为分隔符了。

看来其中是有挺多的人不太喜欢填写地域~

2)使用sort进行排序,使用uniq进行去重复统计。

完整的指令是:

grep "uAddress" data.txt | tr "\t" " "|cut -d " " -f 2 | sort | uniq -c | sort -r

我们进行了两次sort,第一sort是把地域进行一个排列,方便uniq的去重,第二个sort就是按照逆序从大到小排列出人数,方便我们观看。

可以看到北上广确实是主力,应该也是人多的关系,也有5925人没有填写,看到最后上图找亮点~

三、总结

其他的单行数据筛选,方法上就大同小异了,基本上用上面的指令都能凭凑出想要的结果~关于多行匹配和筛选,有机会我会写一篇文章出来单独玩一玩。

这个专题有兴趣的时候我就会更新,东西也不会写很难,就是有点意思就研究研究,也欢迎大家给出宝贵意见~

附上数据下载地址:

data.txt

http://download.csdn.net/detail/yang8456211/9531336

杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。

博文地址:http://blog.csdn.net/yang8456211/article/details/51485723

博客地址:http://blog.csdn.net/yang8456211

本文遵循“署名-非商业用途-保持一致”创作公用协议

时间: 2024-10-08 22:39:46

Bash玩转脚本3之几个指令有趣的筛选京东评价的相关文章

Bash玩转脚本4之搞一套完整的Android反编译与分包工具

一.前言 正在搞IOS的微信支付和支付宝支付,焦头烂额之时,天上掉下来一个Android分包工具的需求,觉得还蛮有意思,其实之前一直想搞一个类似的东西,正好趁着这次机会实践一下. [原文地址] (http://blog.csdn.net/yang8456211/article/details/52513354 ) (先说清楚需求,这个分包工具要干什么) 从产品角度 拿到一个apk安装包,然后用这个包去生成n个包,这n个包需要有特定的标示,能够根据包的标示去收集信息,而且这个n个包彼此不能覆盖安装

Bash玩转脚本1之自己的脚本安装程序

Bash之打造自己的脚本安装器 前言 还是理所当然的前言,我一直想找一套管理脚本的"框架",能让自己杂乱的脚本有点规整.无奈眼界尚浅,未能找到. 因此萌生自己写一点优化脚本的工具来.新手可学习.高手请指正.今天先写一个脚本的安装器,目的在于写完并新脚本之后能够在shell的不论什么位置都能够便捷使用. 安装器干了啥? 一.配置文件 config.ini主要用于配置两个文件夹. 脚本的读取文件夹 生成软链接的存放文件夹 二.读取脚本 递归遍历读取scriptPath文件夹下的脚本文件,排

source、sh、bash、./执行脚本的区别

source.sh.bash../执行脚本的区别 source命令用法: source FileName 作用:在当前bash环境下读取并执行FileName中的命令.该filename文件可以无"执行权限" 注:该命令通常用命令"."来替代. 如:source .bash_profile . .bash_profile两者等效. source(或点)命令通常用于重新执行刚修改的初始化文档. source命令(从 C Shell 而来)是bash shell的内置命

shell命令中用source 和sh(或者bash)执行脚本的区别,以及export的作用

用户登录到Linux系统后,系统将启动一个用户shell,我们暂且称这个shell为shell父. 在这个shell父中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程序. 当使用sh或者bash运行shell脚本程序时,系统将创建一个子shell,我们暂且称为shell子. 此时,系统中将有两个shell,一个是登录时系统启动的shell父,另一个是系统为运行脚本程序创建 的shell子.当一个脚本程序运行完毕,脚本shell子将终止,返回到执行该脚本之前的shell父.

详解shell中source、sh、bash、./执行脚本的区别

复制文章:https://www.jb51.net/article/128918.htm 这篇文章主要介绍了shell中source.sh.bash../执行脚本的区别,需要的朋友可以参考下 1.source命令用法: source FileName 作用:在当前bash环境下读取并执行FileName中的命令.该filename文件可以无"执行权限" 注:该命令通常用命令“.”来替代. 如:source .bash_profile . .bash_profile两者等效. sourc

linux bash启动停止脚本,第二弹

本文是之前的watchdate的shell脚本的改进wdate,同样先上图: 1)脚本加入chkconfig管理  head -5 /etc/init.d/wdate #!/bin/bash #auth:[email protected] # #wdate         Start/Stop the watchdate daemon # # chkconfig: 2345 71 55 chkconfig --add wdate 2)开始贴代码 #!/bin/bash #auth:[email 

bash小小小脚本

1.编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小. [[email protected] scripts]# cat systeminfo.sh #!/bin/bash HostName=`uname -n` Ipv4=`ifconfig |sed -nr '2s#.*addr:(.*)  Bca.*$#\1#gp'` Cpu=`lscpu|sed -n '13p'|tr -s ' 

bash编程练习脚本

1.写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin): 分别这两类用户的个数:通过字符串比较来实现: 通过while循环遍历来实现. while循环的特殊用法(遍历文件的行): while  read VARIABLE; do 循环体: done  < /PATH/FROM/SOMEFILE 依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将基赋值给VARIABLE变量: [[email protected]

命令在bash终端和脚本执行结果不一致问题

#!/bin/bash num=$(ps aux | grep $1 | grep -v grep  | wc -l) echo $num 该脚本执行的num的取值为2 在终端的执行结果应该为0 系统为ubuntu14.04 不知道什么问题,先记录一下.