Linux正则表达式应用

Author Avatar
Brian Lee 4月 09, 2018
  • 在其它设备中阅读本文章

此内容为Linux课程第一次作业,写完了整理好了步骤,就顺便发上来了。


题目要求

从因特网上搜索相关Web网页,处理网页html数据,从中提取出当前时间点北京各监测站的PM2.5浓度,按照格式输出。要求:写出各个处理步骤,并给出解释。

获取网页内容

wget www.pm25china.net/beijing

使用上述指令获取页面,页面自动存储为index.html于本地中

查看文件内容

cat index.html

使用上述指令查看文件内容,确认已成功获取页面,且此指令在后续的操作中也要用于显示

去除每行开头空格

cat index.html | sed -e 's/^[ ]*//g'

为方便处理,使用上述指令去除每行开头的空格

获取时间

cat index.html |sed -e 's/^[ ]*//g'| egrep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]'

如上述指令所示,通过正则表达式匹配时间,获取时间所在的行,显示为:

时间行

接下来使用指令

cat index.html |sed -e 's/^[ ]*//g'| egrep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g'

将时间左右的内容删除掉,得到时间:

时间结果

获取地点与PM2.5值

cat index.html |sed -e 's/^[ ]*//g'| egrep '<td>|[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g'

如上述指令,将td标签添加到 egrep 指令当中,获取所有td标签所在的行,部分显示结果为:

部分结果

由上图可见,为了提取地址与PM2.5数据,需要先将所有标签删除,删除标签便是要删除所有带尖括号的,但是在删除的尖括号内容中不能包含尖括号,使用如下指令:

cat index.html |sed -e 's/^[ ]*//g'| egrep '<td>|[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g' | sed -e 's/<[^<>]*>//g' -e 's/相关城市://g'

将这些标签全部删除,并将多出来的“相关城市:“删除,部分显示结果为:

部分结果2

可以看到有空行存在,接下来通过如下指令删除空行

cat index.html |sed -e 's/^[ ]*//g'| egrep '<td>|[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g' | sed -e 's/<[^<>]*>//g' -e 's/相关城市://g' -e '/^\s*$/d'

部分显示结果为:

部分结果3

按照格式输出内容

由上图可知,每四行为一组数据,其中地址位于四行中的第二行,PM2.5值位于四行中的第四行,即:

  • 当 NR == 1 时,$1为2018-04-07,$2为12:00,将这两个值存为 t1, t2
  • 当 NR%4 == 2 时,$1为地址,将其存为a
  • 当 NR%4 == 0 时,$1为PM2.5值,获取所有想要的信息后,将其使用awk指令格式化输出,指令如下:
cat index.html |sed -e 's/^[ ]*//g'| egrep '<td>|[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g' | sed -e 's/<[^<>]*>//g' -e 's/相关城市://g' -e '/^\s*$/d' | awk 'NR==1 {t1=$1;t2=$2}  NR%4==2 {a=$1} NR%4==0 {printf("%s %s %s %s\n",t1,t2,a,$1)}'

显示为:

部分结果4

此时发现显示的结果是重叠的,原因是每一行数据的结尾都是 ‘\r\n’,’\r’使其发生了回退,所以要将每一行中的 ‘\r’ 去除,指令为:

cat index.html |sed -e 's/^[ ]*//g'| egrep '<td>|[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]' | sed -e 's/<h1.*://g' -e 's/<.*1>//g' | sed -e 's/<[^<>]*>//g' -e 's/相关城市://g' -e '/^\s*$/d' | awk 'NR==1 {t1=$1;t2=$2}  NR%4==2 {a=$1} NR%4==0 {printf("%s %s ,%s ,%s\n",t1,t2,a,$1)}' | sed -e 's/\r//g'

此时输出结果为:

最终结果

此时就得到了最终正确的结果。

本博客采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
本文链接:http://brianleelxt.top/2018/04/09/re/