AWK : 记录文件数据处理的利器

来源:互联网 发布:android反编译apk mac 编辑:程序博客网 时间:2024/06/07 14:09


        这篇文章介绍 AWK 。 它是记录文件数据处理的利器。为什么会这样呢? 

        AWK 隐式地提供了如下功能: 

        (1) 打开每一个文件并读取每一行;对于每一行,根据字段分隔符和行分隔符分割行和字段,并保存文件、行、字段信息; 

        (2) 对每一行进行条件判断和模式匹配,若结果为真则执行相应操作;

        (3) 实际上,提供了记录文件数据处理的框架, 只需要程序员填写条件及操作即可。

                       for each file 

                              for each line 

                                       for each pattern 

                                               if (IsConditionTrue(line, pattern))    do   givenOperation


             AWK 程序结构:

                     BEGIN { init() }    // 只执行一次, 多用于初始化; 

                     PATTERN1   { OPERATION1 }    // 对于每个文件的每一行进行判断, 若模式PATTERN1 为真, 则执行操作 OPERATION1

                     ...

                     PATTERNn   { OPERATIONn }   // 对于每个文件的每一行进行判断, 若模式PATTERNn 为真, 则执行操作 OPERATIONn

                     END  { clean() }    //  只执行一次, 多用于清理工作。

 

             有了这样的框架, 记录文件的数据处理还有多少困难呢? 


             例子: 

             某个 src.java 文件中含有如下代码: 

             

        public final static String CLUNUMREPORT_ALIAS = "clunumrep";public final static String CLUNUMREPORT_PREFIX = "clunumrep.";public final static String TOTAL_KEY = "total";public final static String STOPPED_KEY = "stopped";public final static String RUNNING_KEY = "running";public final static String DESTROYED_KEY = "destroyed";public final static String NEW_KEY = "new";public final static String REPORT_NUM_HOLE_KEY_RES="REPORT_NUM_HOLE_KEY";public final static String REPORT_MON_CIN_AVG_KEY_RES="REPORT_MON_CIN_AVG_KEY";public final static String REPORT_MON_INTER_KEY_RES="REPORT_MON_INTER_KEY";public final static String VM_INTER_KEY_RES="VM_INTER_KEY";

                现在我期望能够将类似 TOTAL_KEY = "total"; 的值对提取出来以方便查看。 用 AWK 怎么做呢 ? 

                awk ' NF==5 { print $5 } ; NF==7 { print $5, $6, $7} ' src.java  >  result.txt 

                OK .  就这么简单。  NF==5 { print $5 } 表示 行的字段数目为 5 时打印第 5 个字段。 默认以空白符为字段分割符。 可以通过 -F 选项设置。


                例子2:  假设有这样的数据文件 src.txt :

  name     no height this last   zhangsan 1  159    95    92   lisi     3  167    88    91  wangwu   6  172    82    84
                 this 表示此次的成绩, last 表示上次的成绩。 要找出成绩进步的同学,也就是说 this 值大于 last .  只要

                 awk ' $4 > $5 { print } '  src.txt 


               例子3:   找出当前目录及子目录下的所有 .java 文件中含有 vm_monitor 模式字符串的记录行,并打印文件、行信息。 

               find . -name '*.java' | xargs awk ' $0 ~ /vm_monitor/ { printf "%s : Line %s :\n%s \n" , FILENAME, FNR, $0 } ' | sed 's/^[[:space:]]\{1,\}/ /' | fmt -w 75


                 够快捷的吧 ? 所以说, 掌握一些重要的 Linux 工具 (Windows 下也可获得!cygwin ), 日常任务其实不需要像 Java 这样重型的武器, 连 C 都不算轻量级了。