引子:

在工作过程中经常要处理各种小数据,同事间会用各种工具方法来处理,比如用java、python、Perl甚至用UE手工处理。但貌似不都方便。

今天举一例子使用shell来处理,来说明shell一行可以解决用其它语言多行的问题。

需求:

有两个文件, device_jingweidu.txt 和device.txt,文件内容如下面格式:

device_jingweidu.txt:

,@QQY.SZF,,三明尤溪水东水库坝上,118.210124,26.176165
,@QQY.SZF,,三明尤溪水东水库坝下,118.210124,26.176165
,@QQY.SZF,,北高镇东乡村码头水位监控,119.156551,25.382036
,@QQY.SZF,,海洋渔业无线接入摄像头,,
,@QQY.SZF,,福州连江山仔水库上游,119.423026,26.225916
,@QQY.SZF,,福州连江山仔水库下游,119.420331,26.230514
,@QQY.SZF,,南平沙溪口水库2,118.09497,26.589413
,@QQY.SZF,,077乌山路市政府门口B,119.303413,26.080324
,@QQY.SZF,,三明安砂水库坝上,117.119716,26.038324
,@QQY.SZF,,三明安砂水库坝下,117.119716,26.038324
,@QQY.SZF,,南平沙溪口水库1,118.09497,26.589413
,@QQY.SZF,,福鼎-沙埕渔港(省),120.424978,27.167177
,@QQY.SZF,,福清东张水库大坝上弧门旁,119.296539,25.70688
,@QQY.SZF,,惠女水库溢洪道桥,118.589045,25.099911
,@QQY.SZF,,福州_连江黄歧渔港,119.889881,26.324397
,@QQY.SZF,,福州_罗源磬里渔排区,119.723905,26.468112

后面两列为经维度

device.txt:

@QQY.SZF,@QQY.SZF,,077乌山路市政府门口B,,
@QQY.SZF,@QQY.SZF,,福清东张水库大坝上弧门旁,,
@QQY.SZF,@QQY.SZF,,宁德_霞浦三沙渔港,,
@QQY.SZF,@QQY.SZF,,南平_九峰桥头,,
@QQY.SZF,@QQY.SZF,,(暂拆)湄洲镇湄洲岛渔港-,,
@QQY.SZF,@QQY.SZF,,092_北大路华林路口,,
@QQY.SZF,@QQY.SZF,,城厢区下尾渔港-,,
@QQY.SZF,@QQY.SZF,,01闽清水口水库水工楼楼顶,,
@QQY.SZF,@QQY.SZF,,02闽清水口水库船闸屋顶,,
@QQY.SZF,@QQY.SZF,,惠安崇武码头,,

后面两列经维度都为0

现需要将device.txt的文件与device_jingweidu.txt文件比对,然后将经纬度更新上次。

需求很简单,根据地点为参数,然后将经纬度更新至device.txt文件

实现:

思路很简单:将原文件存储,然后再读取要更新的文件进行比对,有的就经纬度替换

先看看python是怎么实现的吧,很简单

#coding:utf-8
'''
Created on 2016-5-4
@author: Administrator
''' source_text=r'f:\\Work\\device(带经纬度).txt'
uipath=unicode(source_text,'utf8')
dest_text=r'F:\Work\device.txt' source_dict={}
with open(uipath) as source:
for line in source:
new=line.split(',',4)
source_dict[new[3]]=new[4].strip() dd=open('f:\\Work\\new_devices.txt','wb') with open(dest_text) as dest:
for line in dest:
new=line.split(',') #print new[3],
if new[3] in source_dict:
dd.write(",".join(new[:-2])+","+source_dict[new[3]]+"\r\n") #这里是在windows下,所以用\r\n换行
else:
dd.write(",".join(new[:-2])+","+"0.0"+"\r\n") dd.close()

结果如下:

@QQY.SZF,@QQY.SZF,,077乌山路市政府门口B,119.303413,26.080324
@QQY.SZF,@QQY.SZF,,福清东张水库大坝上弧门旁,119.296539,25.70688
@QQY.SZF,@QQY.SZF,,宁德_霞浦三沙渔港,0.0
@QQY.SZF,@QQY.SZF,,南平_九峰桥头,118.189546,26.639557
@QQY.SZF,@QQY.SZF,,(暂拆)湄洲镇湄洲岛渔港-,0.0
@QQY.SZF,@QQY.SZF,,092_北大路华林路口,119.299107,26.104303
@QQY.SZF,@QQY.SZF,,城厢区下尾渔港-,0.0
@QQY.SZF,@QQY.SZF,,01闽清水口水库水工楼楼顶,118.839738,26.298528
@QQY.SZF,@QQY.SZF,,02闽清水口水库船闸屋顶,118.839738,26.298528

但是,太麻烦,为了处理文本每次都去写个脚本,万一未装python环境呢。

正好,数据正好在linux下,就直接用shell处理吧,首选awk

awk如何处理两个文件呢

使用NR、FNR来处理,如下:

# awk '{print NR,$0}' file1 file2
a b c d
a b d c
a c b d
aa bb cc dd
aa bb dd cc
aa cc bb dd # awk '{print FNR,$0}' file1 file2
a b c d
a b d c
a c b d
aa bb cc dd
aa bb dd cc
aa cc bb dd

知道这一点后,处理我们这个需求更方便了,如下:

awk 'BEGIN{FS=OFS=","}NR==FNR{w[$4]=$5","$6}NR>FNR{for(a in w) if (a==$4){print $1,$2,$3,$4,w[a]}}' device_jingweidu.txt device.txt 

结果如下

@QQY.SZF,@QQY.SZF,,077乌山路市政府门口B,119.303413,26.080324
@QQY.SZF,@QQY.SZF,,福清东张水库大坝上弧门旁,119.296539,25.70688
@QQY.SZF,@QQY.SZF,,南平_九峰桥头,118.189546,26.639557
@QQY.SZF,@QQY.SZF,,092_北大路华林路口,119.299107,26.104303
@QQY.SZF,@QQY.SZF,,01闽清水口水库水工楼楼顶,118.839738,26.298528
@QQY.SZF,@QQY.SZF,,02闽清水口水库船闸屋顶,118.839738,26.298528

看不懂吗?来解释下吧:

1、awk的编码规则:

awk 'BEGIN{action}
模式{action}
END{action}'

2、BEGIN{FS=OFS=","}  FS表示:指定处理分隔符 OFS:输出分隔符,具体可以参考我之前的blog对FS\OFS\IFS等的解释http://www.cnblogs.com/landhu/p/4962521.html

因为这里的分隔都是以,来处理,所以先将分隔符以,号标识

3、NR==FNR{w[$4]=$5","$6}

NR==FNR,按之前NR和FNR说知道,NR==FNR表明在处理第一个文件

w[$4]=$5","$6,这是awk中的关联数组,下标为文件一中的第四列,值为$5,$6 ,存在数据w中

awk中的关联数组是shell中的一个难点,与其它语言的数组还不一样,具体可以参考:http://www.cnblogs.com/chengmo/archive/2010/10/08/1846190.html

4、NR>FNR

表明处理第二个文件

{for(a in w) if (a==$4){print $1,$2,$3,$4,w[a]}}

关联数组的遍历,遍历时将值与第二个文件的第四列对比,有值时,就输出

优化

这个脚本没问题,但存在一个问题,未匹配上的没有显示且脚本有点长,我们来进行优化下,如下

awk 'BEGIN{FS=OFS=","}NR==FNR{w[$4]=$5","$6}NR>FNR && gsub(/0,0/,w[$4])' device_jingweidu.txt device.txt 

结果如下:

@QQY.SZF,@QQY.SZF,,077乌山路市政府门口B,119.303413,26.080324
@QQY.SZF,@QQY.SZF,,福清东张水库大坝上弧门旁,119.296539,25.70688
@QQY.SZF,@QQY.SZF,,宁德_霞浦三沙渔港,
@QQY.SZF,@QQY.SZF,,南平_九峰桥头,118.189546,26.639557
@QQY.SZF,@QQY.SZF,,(暂拆)湄洲镇湄洲岛渔港-,
@QQY.SZF,@QQY.SZF,,092_北大路华林路口,119.299107,26.104303

这个处理就相对好了,没有匹配的数据还有,显示经纬度为空

解释下脚本:

使用了一个awk内置函数gsub,用来替换的,直接将0,0替换数组的值

关于awk内置函数相关文档:http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html

使用shell数据处理数据实例①-------手把手教学版的更多相关文章

  1. 使用 shell 脚本自动获取发版指标数据

    问题背景 大一点的公司都会建立一套规章流程来避免低级错误,例如合入代码前必需经过同行评审:上线前必需提测且通过 QA 验证:全量前必需经过 1%.5%.10%.20%.50% 的灰度过程.尤其是最后一 ...

  2. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

  3. 《Linux命令、编辑器与shell编程》第三版 学习笔记---002

    <Linux命令.编辑器与shell编程>第三版 学习笔记---001 Linux命令.编辑器与shell编程 Shell准备 1.识别Shell类型 echo  $0 echo $BAS ...

  4. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  5. ie页面数据导入共享版

    为了解决自动输入号码的正确率,原来的版本一直采用鼠标检测的方法.但是这个方法在其他ie平台的使用不太方便.于是直接检测ie的方法.现在的这个版本完全不需要鼠标的检测.方便而且快速精准可靠. 经过作者的 ...

  6. 使用LINQ查询数据实例和理解

    使用LINQ查询数据实例和理解 var contacts= from customer in db.Customers where customer.Name.StartsWith("A&q ...

  7. json-lib-2.4-jdk15.jar所需全部JAR包.rar java jsoup解析开彩网api接口json数据实例

    json-lib-2.4-jdk15.jar所需全部JAR包.rar  java jsoup解析开彩网api接口json数据实例 json-lib-2.4-jdk15.jar所需全部JAR包.rar  ...

  8. 主要看思路:区域数据去重 + JavaScript一次性展示几万条数据实例代码

    近期做1功能,Gis地图 基于百度地图api , 会遇到的问题的, 如后台接口给的数据很多,大几千上万的,如果拿了数据直接渲染dom ,这滋味爽爽的. 再遇上 客户端浏览器悲催的,这卡顿就来了... ...

  9. JSONP跨域jQuery处理整理(附天气数据实例)

    写在前面 跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨 ...

随机推荐

  1. Objective-C语法之NSDictionary和NSMutableDictionary

    Java 有Map,可以把数据以键值对的形式储存起来,取值的时候通过key就可以直接拿到对应的值,方便快捷.在Objective-C语言中,词典就是做这样的事情的,和NSArray一样,一个词典对象也 ...

  2. Android学习之——单击ActionBar实现ListView返回顶部

    不知道大家在刷微博时,有没有遇到过,刷新太多,想返回顶部看之前的微博的情况.其实,单击顶部的ActionBar能返回顶部.而不用一直向下拉. 废话不多说,讲讲Android中怎么实现这一功能. 首先, ...

  3. css只改变input输入框光标颜色不改变文字颜色实现方法

    input:focus{color:blue}//光标颜色 input{ text-shadow: 0px 0px 0px red;//文字颜色 -webkit-text-fill-color: tr ...

  4. 一分钟理清Vue-cli 代码构建步骤。

    1. $ npm install vue -cli -g $ vue init webpack project-name $ cd project-name $ npm install $ npm r ...

  5. vs2010如何安装qt插件

    Qt默认使用mingw编译,不支持VS编译器,因此,如果需要用VS开发,需要将Qt重新编译.前提:Qt已安装(http://qt.nokia.com/downloads-cn),VS已安装. 1.下载 ...

  6. 用highcharts展现你的数据

    摘要: 前面已经分享过图表插件,今天在来将下如何使用highcharts来绘制图表.highcharts支持在线定制,你可以选择你所需要的模块,然后点击build就会生成一个js文件链接,右键保存到本 ...

  7. webdriver+expected_conditions二次封装

    结合这两种方法对代码做二次封装,可以提升脚本性能 例: #coding:utf-8 #封装元素方法from selenium import webdriverfrom selenium.webdriv ...

  8. Windows程序执行过程

    Windows应用程序: WinMain函数(入口函数): 1. 设计窗体类,注冊窗体类.WNDCLASS 2. 创建窗体,显示及更新窗体. 3. 消息循环. 窗体过程函数(回调函数):WindowP ...

  9. 在taro中跳转页面的时候执行两遍componentDidMount周期的原因和解决方法

    在做taro跳转的时候,发现在跳转后的页面会走两遍componentDidMount周期,查看了github上的issues,发现是跳转路由带参为中文引起的,只要把中文参数进行urlencode解决 ...

  10. Android学习之BitMap用法实例

    下面简单说明了BitMap的用法: 从服务器下载一张图片,显示在ImageView控件上,并将该图片保存在移动设备的SD上. // 根据网络URL获取输入流 public InputStream ge ...