爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 39641|回复: 47

[经验总结] 气象数据处理脚本篇

  [复制链接]

新浪微博达人勋

发表于 2012-6-16 13:12:54 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 雪花纷飞 于 2012-6-16 13:59 编辑

       气象领域常需要和数据处理打交道,一般气象数据分为两类:一类是专有压缩无格式数据,如nc数据;另一类是常见有格式文本数据,如txt、csv数据。前者需要编写相应Fortran程序或用专用程序如grads读取,而后者可用vim文本编辑器、execl等直接查看数据内容,并能直接手动提取数据。今天讲讲对常见有格式数据的处理。如果数据样本很少,手动提取无妨,但一涉及到成百上千的数据样本处理时,手动处理就不合时宜了,在这里介绍Linux下两个非常有用的文本处理工具:sed和awk。其中sed擅长于对行操作,即以为处理对象进行替换、删除、编辑等操作;而awk擅长对列操作,常用于提取整列数据。

首先简单介绍下sed和awk用法。
  • sed

    sed是一种非交互式的编辑器,只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。sed编辑器没有破坏性,不会修改文件,除非使用shell重定向来保存输出结果。它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)或临时缓冲,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件最后一行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改或破坏原文件。
1.JPG    


sed通过定址决定对哪些行进行编辑。地址的形式可以是数字、正则表达式或二者的结合。如果没有指定地址,sed将处理所有行。地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。

    sed命令告诉sed对指定行进行何种操作,包括打印、删除、修改等。

格式
  1. sed  'command'  filename(s)
复制代码
常用命令:  d (delete,删除行)            
             p (print,打印行)
             s (substitute,用一个字符替换另一个)


举例
sed '2,4d'  test       ----删除test文件中第2-4行
sed '/me/d' test       ----删除test文件中所有包含me字样的行
sed 's/me/you/g' test  ----将文中所有包含me字样的替换成you,g(global)表示所有行


2. awk
格式:   

  1. awk  'pattern {action}' filename
复制代码

awk指令由模式pattern、操作action、或模式与操作的组合组成。模式是由括在两个正斜杠(/ /)之间的正则表达式、一个或多个awk操作符组成的表达式组成。awk以逐行方式扫描,从第一行到最后一行,以查找匹配某个特定pattern的文本行,并对这些行执行{ }中action。如果只给出pattern而未指定action,则所有匹配该pattern的行都显示在屏幕上;如果只指定动作而未定义模式,会对所有输入行指定action。

工作原理用一个名为wind.txt的文件说明。

date       uwind     vwind
20110101     3.5       4.5  
20110102     3.5       4.5
20110103     3.5       4.5

输入命令:
  1. awk  '{print $1,$3}'  wind.txt
复制代码


(1)awk把每一个以换行符结束的行称为一个记录,并将这一行赋给内部变量$0。从第一行开始输入。      
     将“date       uwind     vwind”这一行赋给变量$0。

(2)然后,行被空格分解成字段,每个字段存储在已编号的变量中,从$1开始,$2,$3,...。那么awk如何知道      空格是用来分隔字段的呢?这是由另一个内部变量FS来确定的。默认为空格(包括Tab和空格符)。如果需要使用其他的字符分隔字段,如冒号或破折号,则通过设置FS变量达到目的。
  1.              $1              $2           $3   
  2. $0         date         uwind     vwind
  3. $0       20110101     3.5       4.5  
  4. $0       20110102     3.5       4.5
  5. $0       20110103     3.5       4.5
复制代码

(3)awk指定action为print,打印$1和$3字段(也即第一列和第三列)。先输出第一行的第一列和第三列。   
  1.   date      vwind
复制代码

(4)awk输出一行后,又从文件中获取下一行,并将其存储到$0中,覆盖原来内容,然后将新的字符串分隔成字段并进行处理。一直持续到最后一行。输出结果为:
  1. date       vwind

  2. 20110101      4.5  
  3. 20110102      4.5
  4. 20110103      4.5
复制代码

*******************************华丽的分割线************************************

    以下通过对气象数据处理实例进行讲解,关于sed和awk详细语法,可以google之,
这里只是想启发大家换种思路处理数据,希望能起到抛砖引玉的作用。

现有一个风速数据wind_2011-01-05.txt(咳咳,我自己编造的,勿拍),如下图file:///C:/Documents%20and%20Settings/cams/Local%20Settings/Temp/Wiz/d3c753e9-953f-4362-b915-9bd4b973b967_0_files/8523062.png
2.JPG
该数据特点是开头5行为#开始的注释语句,自第7行开始为数据记录,共有4列数据,分别是data、time、uwind、vwind。

数据处理要求:提取time和uwind两列数据放到uwind.txt中。

思路:要提取time和uwind两列数据,适合用awk操作,但由于注释行的干扰不能直接使用awk,所以首先需要删除开头注释行,可以看出所有注释行共有的特点是以#开头,这样可以请出sed工具删除以#开头的行。(写脚本一般流程是先在命令行中测试,测试成功后将相关语句整合到一个脚本中。)

  1. sed  '/#/d'  ./wind_2011-01-05.txt
复制代码
输出结果为:
file:///C:/Documents%20and%20Settings/cams/Local%20Settings/Temp/Wiz/d3c753e9-953f-4362-b915-9bd4b973b967_0_files/9742656.png 3.JPG

另一种思路是,一般注释行都是在固定几行,可以删除1-5行,效果类似。

  1. sed  '1,5d' ./wind_2011-01-05.txt
复制代码

通过管道,将处理完注释行的文本内容传给awk提取列数据,

  1. sed  '/#/d'  ./wind_2011-01-05.txt  | awk '{print $2,$3}
复制代码
file:///C:/Documents%20and%20Settings/cams/Local%20Settings/Temp/Wiz/d3c753e9-953f-4362-b915-9bd4b973b967_0_files/10445890.png 输出结果:
4.JPG
处理后的数据满足要求,可以写脚本啦。创建脚本sample.sh,
  1. #! /bin/bash
  2. sed  '/#/d'  ./wind_2011-01-05.txt | awk  '{print $2, $3}' > uwind.txt
复制代码


保存退出,在执行前别忘了修改执行权限,
  1. chmod  a+x ./sample.sh
复制代码

执行 ./sample.sh ,在同一目录下会看到uwind.txt。

       一个气象数据可以这样处理,如果有成百个数据要处理,不可能每次都改下文件名吧,很自然的想到用循环处理,shell脚本中提供了for循环。比如说现有以上格式的2011年全年数据,需要处理怎么办?下一篇继续讨论

扩展阅读:
1.sed学习笔记http://www.tsnc.edu.cn/tsnc_wgrj/doc/sed.htm

2.awk学习笔记,http://www.linux.gov.cn/shell/awk.htm#id2861680

3.UNIX shell范例精解(第4版)





32786953.PNG

评分

参与人数 5金钱 +85 贡献 +22 体力 +120 收起 理由
Forcast + 10 + 2 赞一个!
善人/jw + 22 + 6
topmad + 20 + 5 + 10 加大火力
言深深 + 18 + 4 + 110
mofangbao + 15 + 5 加油~

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

0
早起挑战累计收入
发表于 2012-6-16 13:49:05 | 显示全部楼层
shell脚本真是强大~
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-16 13:34:46 | 显示全部楼层
好东西,对研究非常有用
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-16 14:34:05 | 显示全部楼层
太棒了!前段时间刚研究过sed,学习了!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-17 11:48:08 | 显示全部楼层
果断顶起啊
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-8-27 09:19:26 | 显示全部楼层
还是挺不错的
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-8-27 10:49:55 | 显示全部楼层
挺不错!顶起啊
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-9-4 14:54:43 | 显示全部楼层
真是不错,学习!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-9-19 11:20:27 来自手机 | 显示全部楼层
好东西,非常有用!Linux下很实用!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-9-19 16:33:54 | 显示全部楼层
很实用,谢谢!
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表