美文网首页
gawk基础

gawk基础

作者: 御浅永夜 | 来源:发表于2018-01-21 22:46 被阅读0次

前言

本文并不是一篇gawk手册一样的文章,所以不可能条理清楚的告诉你如何使用,而是循序渐进的描述自己对这个工具的掌握。
gawk表现的更像一门语言,像使用一门语言那样的使用它的基本操作就能达到我自己的需求了。

1. 拆分、选择

我们大概什么时候使用gawk呢?就我自己来说,就是对一个文件的每一行按照分隔符拆分成多个元素,然后选取自己需要的,即拆分、选择。

例如下面的一个文件test.file(姓名:学号:成绩)

Alice:1:98
Bob:2:70

使用gawk程序的基本格式:gawk option program file
option->-F::指定分隔符,通过:将每一行分隔
program->'{print $1}':打印出分隔出来的元素1
file->test.file:指定输入文件,如果未指定,则从STDIN等待输入

renz@renz-ubuntu:~/work$ gawk -F: '{print $1}' test.file
Alice
Bob
renz@renz-ubuntu:~/work$ gawk -F: '{print $2}' test.file 
1
2
renz@renz-ubuntu:~/work$ gawk -F: '{print $3}' test.file 
98
70

gawk以文件的每行为一个单位,Alice:1:98:分为Alice198,拆分的元素可以通过$1、$2、$3取出。

2. 多重拆分、选择

得益于可以在程序中使用多个命令命令1 | 命令2,我们可以对已经拆分的结果再次拆分,这使我可以应对稍复杂的内容。

例如class.xml文件:

<class>
    <students>
        <student>
            <name>Alice</name>
            <serial>1</serial>
            <score>98</score>
        </student>
        <student>
            <name>Bob</name>
            <serial>2</serial>
            <score>70</score>
        </student>
    </students>
</class>

我想打印出所有同学的名字,策略就是先通过name分隔为< >Alice</ >即$1=' <',$2='>Alice<',$3='>'

renz@renz-ubuntu:~/work$ gawk '{FS="name"; print $2}' class.xml 




>Alice</



>Bob</




然后对$2通过>分隔为$1='',$2='Alice<'

renz@renz-ubuntu:~/work$ gawk '{FS="name"; print $2}' class.xml | gawk '{FS=">"; print $2}'




Alice</



Bob</




然后再对$2通过<分隔为$1='Alice',$2=''。

renz@renz-ubuntu:~/work$ gawk '{FS="name"; print $2}' class.xml | gawk '{FS=">"; print $2}' | gawk '{FS="<"; print $1}'




Alice



Bob




3. 变量与循环结构的使用

3.1 为什么要使用变量

上一例中的xml文件完美到强迫症的人都会觉得舒服,因为是专门排版给人看的,未经过排版的class2.xml文件如下:

<class>
    <students>
        <student><name>Alice</name><serial>1</serial><score>98</score></student><student><name>Bob</name><serial>2</serial><score>70</score></student>
    </students>
</class>

这个文件的结构对于使用xpath解析来说没有任何影响,但是对于使用gawk解析的我来说

renz@renz-ubuntu:~/work$ gawk '{FS="name"; print $2}' class2.xml | gawk '{FS=">"; print $2}' | gawk '{FS="<"; print $1}'


Alice


Bob不见了!
原因在于第二次解析的时候,Bob在$4中,而我们只解析了$2。

renz@renz-ubuntu:~/work$ gawk '{FS="name"; print $1,$2,$3,$4,$5}' class2.xml
<class>    
    <students>    
        <student><serial>1</serial>< >Alice</ ></student><student><serial>2</serial>< >Bob</ ></student>
    </students>    
</class>    

于是我们只要改变策略就可以了:

学生数 解析的参数
1 $2
2 $2,$4
3 $2,$4,$6
... ...
n $2,$4,...,$2n

但是<student>是一个可以无限制添加的节点啊,每多一个学生就要修改一下程序吗?
在工作中我遇到这种情况的时候,内心是崩溃的。于是经验不足的我产生了一个大胆的想法,gawk能不能够告诉我它究竟分隔了多少个元素,这样我就可以通过循环来确定每次要解析的元素。

我就是这样查到了gawk的高级特性。

3.2 如何使用变量

两种不同类型的变量:

  1. 内建变量
  2. 自定义变量

3.2.1 内建变量

字段和记录分隔符变量
内建变量是用来使用程序里的特定功能的,解决诸如我们用什么来分隔字符串,再以怎样的格式显示出来。

变量 描述
FS 输入字段分隔符
OFS 输出字段分隔符(默认空格)

数据变量
用来掌控环境变化的,还可以提取shell环境的信息。

变量 描述
ARGC 命令行参数个数
ARGV 包含命令行参数的数组
FILENAME 用作gawk输入数据的数据文件的文件名
NF 数据文件中的字段总数

还记得我最开始的需求吗,我需要知道按照分隔符到底分了多少个字段,这样我就可以根据分隔的字段总数来选取解析的参数,NF就可以帮助我完成这件事。我们只需解析偶数,一直解析到NF-1就能不管一行有多少,都能遍历取出了:

renz@renz-ubuntu:~/work$ awk '{FS="name"; i=2;while (i<NF){ print $i;i++;i++} }' class2.xml | gawk '{FS=">"; print $2}'

Bob</

然而出了点问题,太尴尬了,毕竟我也是新手。但是上面的例子同时展示了两个新的特性——自定义变量循环结构,这就是为什么我们可以把他当作一门语言来学的原因,对了,后面将学到还可以声明函数:)。

3.2.2 自定义变量

3.3 结构化语句

3.4 函数

相关文章

  • gawk基础

    前言 本文并不是一篇gawk手册一样的文章,所以不可能条理清楚的告诉你如何使用,而是循序渐进的描述自己对这个工具的...

  • gawk 相关总结

    一. gawk 基础 gawk 程序脚本用一对花括号来定义,必须将命令放到两个花括号中。由于 gawk 命令行假定...

  • gawk

    gawk基本使用 gawk options program file gawk -F '{commond1;com...

  • gawk快速指南

    gawk是awk的GNU版本,采用编程语言的形式 gawk命令格式 gawk options program fi...

  • Linux中的部分awk命令 2019-11-18

    awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU...

  • 21. Linux awk 命令

    AWK 官方手册:http://www.gnu.org/software/gawk/manual/gawk.htm...

  • gawk Ⅰ

    awk vs gawk 除了VI这种交互式的文本编辑器(interactive text editor),Linu...

  • 硬盘容量邮件报警功能

    1. 安装gawk:sudo apt install gawk; 2. 安装mail:sudo apt-get i...

  • awk

    awk介绍 有多种版本:New awk(nawk),GNU awk(gawk) gawk:模式扫描和处理语言 基本...

  • linux shell编程中有的命令组合

    1、字符串转换大小写 gawk '{print toupper($0)}' //转换为大写 gawk '{prin...

网友评论

      本文标题:gawk基础

      本文链接:https://www.haomeiwen.com/subject/ojfqaxtx.html