天天看點

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,如需轉載請自行聯系原作者