气象数据处理脚本篇

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

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

 

 

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

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

格式:    

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
格式:   
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
 
输入命令:
awk '{print $1,$3}' wind.txt
(1)awk把每一个以换行符结束的行称为一个记录,并将这一行赋给内部变量$0。从第一行开始输入。
      将“date       uwind     vwind”这一行赋给变量$0。
(2)然后,行被空格分解成字段,每个字段存储在已编号的变量中,从$1开始,$2,$3,...。那么awk如何知道空格是用来分隔字段的呢?这是由另一个内部变量FS来确定的。默认为空格(包括Tab和空格符)。如果需要使用其他的字符分隔字段,如冒号或破折号,则通过设置FS变量达到目的。
          $1          $2        $3   
$0     date       uwind     vwind
$0    20110101     3.5       4.5 
$0    20110102     3.5       4.5
$0    20110103     3.5       4.5
 
(3)awk指定action为print,打印$1和$3字段(也即第一列和第三列)。先输出第一行的第一列和第三列。
        date      vwind
 
(4)awk输出一行后,又从文件中获取下一行,并将其存储到$0中,覆盖原来内容,然后将新的字符串分隔成字段并进行处理。一直持续到最后一行。输出结果为:
 date          vwind
20110101        4.5 
20110102        4.5
20110103        4.5
 
 
**********************************************************
 
以下通过对气象数据处理实例进行讲解,关于sed和awk详细语法,可以google之,这里只是想启发大家换种思路处理数据,希望能起到抛砖引玉的作用.
 

现有一个风速数据wind_2011-01-05.txt(咳咳,我自己编造的,勿拍),如下图


 
该数据特点是开头5行为#开始的注释语句,自第7行开始为数据记录,共有4列数据,分别是data、time、uwind、vwind。
 
数据处理要求:提取time和uwind两列数据放到uwind.txt中。
 
思路:要提取time和uwind两列数据,适合用awk操作,但由于注释行的干扰不能直接使用awk,所以首先需要删除开头注释行,可以看出所有注释行共有的特点是以#开头,这样可以请出sed工具删除以#开头的行。(写脚本一般流程是先在命令行中测试,测试成功后将相关语句整合到一个脚本中。)
       
sed  '/#/d'  ./wind_2011-01-05.txt 
输出结果为:

 
另一种思路是,一般注释行都是在固定几行,可以删除1-5行,效果类似。
    
sed  '1,5d' ./wind_2011-01-05.txt

 

通过管道,将处理完注释行的文本内容传给awk提取列数据,
    
sed  '/#/d'  ./wind_2011-01-05.txt  | awk '{print $2,$3}
 输出结果:

处理后的数据满足要求,可以写脚本啦。创建脚本sample.sh,
#! /bin/bash
sed  '/#/d'  ./wind_2011-01-05.txt | awk  '{print $2, $3}'\
  > uwind.txt
保存退出,在执行前别忘了修改执行权限,
chmod  a+x ./sample.sh
执行 ./sample.sh ,在同一目录下会看到uwind.txt。
 
 
     一个气象数据可以这样处理,如果有成百个数据要处理,不可能每次都改下文件名吧,很自然的想到用循环处理,shell脚本中提供了for循环。比如现有以上格式的2011年全年数据,需要处理怎么办?下一篇继续讨论哈。
 
扩展阅读:
 
 
3.UNIX shell范例精解(第4版)
 
 

转载于:https://www.cnblogs.com/Parallel-Life/archive/2012/06/16/2551820.html

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值