天天看点

gawk高级使用

BEGIN和END关键字是来用来读取数据流之前或之后执行命令的特殊模式

1、内建变量

            FIELDWIDTHS:由空格分隔开的的定义每个数据字段确切宽度的一列数字

            FS:输入字段分隔符

            RS:输入数据行分隔符

            OFS:输出字段分隔符

            ORS:输出数据行分隔符

1

2

3

4

<code>[root@node3 conf]# cat data2</code>

<code>data1,data2,data3,data4,data5</code>

<code>data6,data7,data8,data9,data10</code>

<code>data11,data12,data13,data14,data15</code>

<code>[root@node3 conf]# gawk </code><code>'BEGIN{FS=",";OFS="-"} {print $1,$2,$3}'</code> <code>data2</code>

<code>data1-data2-data3</code>

<code>data6-data7-data8</code>

<code>data11-data12-data13</code>

数据流占多行情况下

    把RS变量设置成空白字符串,然后在数据行间留一个空白行。gawk会把每个空白行当作一个数据行分隔符

5

6

7

8

9

<code>[root@node3 conf]# cat data3</code>

<code>Tom Mullen</code>

<code>123</code> <code>Main Street</code>

<code>Chicago.IL </code><code>6001</code>

<code>(</code><code>312</code><code>)</code><code>555</code><code>-</code><code>1234</code>

<code>Frank Williams</code>

<code>456</code> <code>Oak street</code>

<code>Indianpolis.IN </code><code>46201</code>

<code>(</code><code>317</code><code>)</code><code>55</code><code>-</code><code>9786</code>

<code> </code><code>[root@node3 conf]# gawk </code><code>'BEGIN{FS="\n";RS=""} {print $1,$4}'</code> <code>data3</code>

<code>Tom Mullen (</code><code>312</code><code>)</code><code>555</code><code>-</code><code>1234</code>

<code>Frank Williams (</code><code>317</code><code>)</code><code>55</code><code>-</code><code>9786</code>

2、数据变量

            FNR:当前数据文件中的数据行数

            NF:数据文件中的字段总数

            NR:已处理的输入数据行数目

<code>[root@node3 conf]# gawk </code><code>'BEGIN{FS=":";OFS=";"}{print $1,$NF}'</code> <code>/etc/passwd</code>

<code>root;/bin/bash</code>

<code>bin;/sbin/nologin</code>

<code>daemon;/sbin/nologin</code>

<code>adm;/sbin/nologin</code>

<code>lp;/sbin/nologin</code>

10

11

12

13

14

15

16

17

<code>[root@node3 conf]# gawk '</code>

<code>BEGIN{FS=</code><code>","</code><code>}</code>

<code>{print $</code><code>1</code><code>,</code><code>"FNR="</code><code>FNR,</code><code>"NR="</code><code>NR}</code>

<code>END{print </code><code>"there were"</code><code>,NR,</code><code>"records processed"</code><code>}' data2 data2</code>

<code>data1 FNR=</code><code>1</code> <code>NR=</code><code>1</code>

<code>data6 FNR=</code><code>2</code> <code>NR=</code><code>2</code>

<code>data11 FNR=</code><code>3</code> <code>NR=</code><code>3</code>

<code>data1 FNR=</code><code>1</code> <code>NR=</code><code>4</code>

<code>data6 FNR=</code><code>2</code> <code>NR=</code><code>5</code>

<code>data11 FNR=</code><code>3</code> <code>NR=</code><code>6</code>

<code>there were </code><code>6</code> <code>records processed</code>

3、自定义变量

     变量名不能以数字开头,

<code>&gt; BEGIN{</code>

<code>&gt; testing=</code><code>"this is a test"</code>

<code>&gt; print testing</code>

<code>&gt; }'</code>

<code>this</code> <code>is</code> <code>a test</code>

<code>[root@node3 conf]# gawk </code><code>'BEGIN{X=4;X=X*2+3;print X}'</code>

<code>11</code>

 在命令行上给变量赋值

<code>[root@logicserver tmp]# cat script1</code>

<code>#!/bin/bash</code>

<code>#</code>

<code>{print $n}</code>

<code>[root@logicserver tmp]# cat data3</code>

<code>[root@logicserver tmp]# gawk -f script1 n=</code><code>2</code> <code>data3</code>

<code>data2</code>

<code>data7</code>

<code>data12</code>

在设置变量后,这个值在代码的BEGINU部分不可用

<code>[root@logicserver tmp]# vim script1</code>

<code>BEGIN{print </code><code>"the starting value is "</code><code>,n;FS=</code><code>","</code><code>}</code>

<code>[root@logicserver tmp]# gawk -f script1 n=</code><code>3</code> <code>data3</code>

<code>the starting value </code><code>is</code>  

<code>data3</code>

<code>data8</code>

<code>data13</code>

加上-v,允许你指定BEGIN代码部分之前设定的变量

<code> </code><code>[root@logicserver tmp]# gawk -f script1 -v n=</code><code>3</code> <code>data3</code>

<code>the starting value </code><code>is</code>  <code>3</code>

4、遍历数组

         for (var in array)

         {

            statements

         }

for语句在每次将关联数组array的下一个索引值赋给变量var时,执行一遍statements。

记住这个变量是索引值而不是数组元素的值

<code>[root@logicserver tmp]# gawk 'BEGIN{</code>

<code>var</code><code>[</code><code>"a"</code><code>]=</code><code>1</code>

<code>var</code><code>[</code><code>"g"</code><code>]=</code><code>2</code>

<code>var</code><code>[</code><code>"m"</code><code>]=</code><code>3</code>

<code>var</code><code>[</code><code>"u"</code><code>]=</code><code>4</code>

<code>for</code> <code>(test </code><code>in</code> <code>var</code><code>)</code>

<code>{</code>

<code>print </code><code>"Index:"</code><code>,test,</code><code>" - Valuse:"</code><code>,</code><code>var</code><code>[test]</code>

<code>}</code>

<code>}'</code>

<code>Index: u  - Valuse: </code><code>4</code>

<code>Index: m  - Valuse: </code><code>3</code>

<code>Index: a  - Valuse: </code><code>1</code>

<code>Index: g  - Valuse: </code><code>2</code>

删除数组的变量

从关联数组中删除数组索引要用一个特别命令

delete array[index]

18

<code>   </code><code>print </code><code>"Index:"</code><code>,test,</code><code>"- Value"</code><code>,</code><code>var</code><code>[test]</code>

<code>delete</code> <code>var</code><code>[</code><code>"g"</code><code>]</code>

<code>print </code><code>"------------"</code>

<code>Index: a - Value </code><code>1</code>

<code>Index: g - Value </code><code>2</code>

<code>------------</code>

5、匹配操作符

匹配操作符(~),允许将正则表达式限定在数据行中的特定数据字段。

$1 ~/expression/

用正则表达式/^data2/来匹配第二个数据段,过滤第二个字段以文本data2为开头的行

<code>data21,data22,data23,data24,data25</code>

<code>[root@logicserver tmp]# gawk </code><code>'BEGIN{FS=","} $2 ~/[^data2]/{print $0}'</code> <code>data3</code>

gawk程序脚本常用在数据文件查找特定数据元素的强大工具

<code>[root@logicserver tmp]# gawk -F: </code><code>'$1 ~/root/{print $1,$NF}'</code> <code>/etc/passwd</code>

<code>root /bin/bash</code>

用!符号来排除正则表达式的匹配

$1 !~/expression/

<code>gawk -F: </code><code>'$1 !~/root/{print $1,$NF}'</code> <code>/etc/passwd</code>

6、数学表达式

 x == y

 x &lt;= y

 x &lt; y

 x &gt;= y

 x &gt; y

如显示所有属于root用户组的(组ID为0)的系统用户

<code> </code><code>[root@logicserver tmp]# gawk -F: </code><code>'$4==0{print $1}'</code> <code>/etc/passwd</code>

<code>root</code>

<code>sync</code>

<code>shutdown</code>

<code>halt</code>

<code>operator</code>

 对文本数据使用表达式,必须要小心,跟正则表达式不同,表达式必须完全匹配

<code>[root@logicserver tmp]# gawk -F, </code><code>'$1== "data1" {print $1}'</code> <code>data3</code>

<code>data1</code>

6、if语句

 if (condition)

 statement1

或者 if (condition) statement1

<code>[root@logicserver tmp]# cat data4</code>

<code>10</code>

<code>5</code>

<code>3</code>

<code>13</code>

<code>55</code>

<code>[root@logicserver tmp]# gawk </code><code>'{if ($1&gt;20) print $1}'</code> <code>data4</code>

<code>[root@logicserver tmp]# gawk '{</code>

<code>&gt; </code><code>if</code> <code>($</code><code>1</code><code>&gt;</code><code>20</code><code>)</code>

<code>&gt; {</code>

<code>&gt;    x=$</code><code>1</code> <code>* </code><code>2</code>

<code>&gt;    print x</code>

<code>&gt; }</code>

<code>&gt; }' data4</code>

<code>110</code>

gawk的if语句也支持else子句,允许在if语句条件不成立的情况下执行一条或多条语句。

<code> </code><code>[root@logicserver tmp]# gawk '{</code>

<code>&gt; </code><code>if</code> <code>($</code><code>1</code><code>&gt;</code><code>100</code><code>)</code>

<code>&gt;   x=$</code><code>1</code> <code>* </code><code>2</code>

<code>&gt;   print x</code>

<code>&gt; } </code><code>else</code>

<code>&gt;   x=$</code><code>1</code> <code>/ </code><code>2</code>

<code>&gt; }}' data4</code>

<code>2.5</code>

<code>1.5</code>

<code>6.5</code>

<code>27.5</code>

也可以这么写

if (condition) statement1:else statement2

<code>[root@logicserver tmp]# gawk </code><code>'{if ($1&gt;100) print $1*2;else print $1/2}'</code> <code>data4</code>

7、while语句

while (condition)

{

   statement1

}

<code>[root@logicserver tmp]# cat data5</code>

<code>120</code> <code>130</code> <code>135</code>

<code>160</code> <code>113</code> <code>140</code>

<code>145</code> <code>170</code> <code>215</code>

<code>total=</code><code>0</code>

<code>i=</code><code>1</code>

<code>while</code> <code>(i&lt;</code><code>4</code><code>)</code>

<code>{   total+=$i</code>

<code>   </code><code>i++</code>

<code>avg=total/</code><code>3</code>

<code>print </code><code>"Averaget:"</code><code>,avg</code>

<code>}' data5</code>

<code>Averaget: </code><code>128.333</code>

<code>Averaget: </code><code>137.667</code>

<code>Averaget: </code><code>176.667</code>

<code>Averaget: </code><code>0</code>

8、do-while语句

   do

    {

      statement1

    } while (condition)

<code>do</code>

<code>  </code><code>total+=$i</code>

<code>  </code><code>i++</code>

<code>}</code><code>while</code> <code>(total&lt;</code><code>150</code><code>)</code>

<code>print total}' data5</code>

<code>250</code>

<code>160</code>

<code>315</code>

9、for语句

for (variable assignment;condition;interation process)

19

20

21

22

23

24

25

26

<code>&gt; tatal=</code><code>0</code>

<code>&gt; </code><code>for</code> <code>(i=</code><code>1</code><code>;i&lt;</code><code>4</code><code>;i++)</code>

<code>&gt;    total+=$i</code>

<code>&gt; avg=total/</code><code>3</code>

<code>&gt; print </code><code>"Average:"</code><code>,avg</code>

<code>&gt; }' data5</code>

<code>Average: </code><code>128.333</code>

<code>Average: </code><code>266</code>

<code>Average: </code><code>442.667</code>

<code>[root@logicserver tmp]# gawk </code><code>'{for (i=1;i&lt;4;i++) total+=$i;avg=total/3;print "Average:",avg}'</code> <code>data5</code>

10、格式化打印

<a href="http://s3.51cto.com/wyfs02/M01/73/62/wKioL1X72Efi0JoFAAE51wN1SGA949.jpg" target="_blank"></a>

在printf命令末尾手动添加换行符来生成新行

如果需要几个单独的printf命令来在同一行上打印多个输出

<code>[root@logicserver tmp]# gawk </code><code>'BEGIN{FS=","}{printf "%s ",$1}END{printf "\n"}'</code> <code>data3</code>

<code>data1 data6 data11 data21</code>

<code>[root@logicserver tmp]# gawk </code><code>'BEGIN{FS=","}{printf "%s ",$1}'</code> <code>data3</code>

<code>data1 data6 data11 data21 [root@logicserver tmp]#</code>

本文转自 zouqingyun 51CTO博客,原文链接:http://blog.51cto.com/zouqingyun/1695991,如需转载请自行联系原作者