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>> BEGIN{</code>
<code>> testing=</code><code>"this is a test"</code>
<code>> print testing</code>
<code>> }'</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 <= y
x < y
x >= y
x > 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>20) print $1}'</code> <code>data4</code>
<code>[root@logicserver tmp]# gawk '{</code>
<code>> </code><code>if</code> <code>($</code><code>1</code><code>></code><code>20</code><code>)</code>
<code>> {</code>
<code>> x=$</code><code>1</code> <code>* </code><code>2</code>
<code>> print x</code>
<code>> }</code>
<code>> }' data4</code>
<code>110</code>
gawk的if語句也支援else子句,允許在if語句條件不成立的情況下執行一條或多條語句。
<code> </code><code>[root@logicserver tmp]# gawk '{</code>
<code>> </code><code>if</code> <code>($</code><code>1</code><code>></code><code>100</code><code>)</code>
<code>> x=$</code><code>1</code> <code>* </code><code>2</code>
<code>> print x</code>
<code>> } </code><code>else</code>
<code>> x=$</code><code>1</code> <code>/ </code><code>2</code>
<code>> }}' 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>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<</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<</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>> tatal=</code><code>0</code>
<code>> </code><code>for</code> <code>(i=</code><code>1</code><code>;i<</code><code>4</code><code>;i++)</code>
<code>> total+=$i</code>
<code>> avg=total/</code><code>3</code>
<code>> print </code><code>"Average:"</code><code>,avg</code>
<code>> }' 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<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,如需轉載請自行聯系原作者