gawk是一門功能豐富的編程語言,你能夠經過它所提供的各類特性來編寫好幾程序處理數據。 linux
gawk編程語言支持兩種不一樣類型的變量:正則表達式
內建變量和自定義變量shell
gawk程序使用內建變量來引用程序數據裏的一些特殊功能編程
1.字段和記錄分隔符變量數組
數據字段變量:容許你使用美圓符和字段在該記錄中的位置值來引用記錄對應的字段。bash
要引用第一個字段就用變量$1,第二個就用$2,….以此類推。編程語言
數據字段是由分隔符來劃定的。默認字段分隔符是一個空白字符,也就是空格或者製表符。函數
有一組內建變量用於控制gawk如何處理輸入輸出數據中的字段和記錄,見下表:spa
變量命令行 |
描述 |
FIELDWIDTHS |
有空格分隔的一列數字,定義每一個數據字段的確切寬度 |
FS |
輸入字段分隔符 |
RS |
輸入記錄分隔符 |
OFS |
輸出字段分隔符 |
ORS |
輸出記錄分隔符 |
1)print命令會自動將OFS變量的值放置在輸出中的每一個字段間。
實例:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1
data11,data12,data13,data14
data21,data22,data23,data24
data31,data32,data33,data34
data41,data42,data43,data44
data51,data52,data53,data54
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1
data11-data12-data13
data21-data22-data23
data31-data32-data33
data41-data42-data43
data51-data52-data53
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","; OFS="<-->"} {print $1,$2,$3}' data1
data11<-->data12<-->data13
data21<-->data22<-->data23
data31<-->data32<-->data33
data41<-->data42<-->data43
data51<-->data52<-->data53
xcy@xcy-virtual-machine:~/shell/22zhang$
2) FIELDWIDTHS變量容許你不依靠字段分割符來讀取記錄。一旦這是了FILEDWIDTFS變量,gawk就會忽略FS變量。
警告:一旦設定了FIELDWIDTHS變量的值,就不能再改變了。這種方法並不適用於變長的字段
有寫數據沒有指定分隔符,而是放在特定的列,這時候就能夠用FIELDWIDTHS了:
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data2
1005.3246782.37
115-2.343324.08
05828.3452433.1
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data2
100 5.324 67 82.37
115 -2.34 33 24.08
058 28.34 52 433.1
xcy@xcy-virtual-machine:~/shell/22zhang$
3)RS和ORS定義了gawk程序如何處理數據流中的字段。默認這兩個都是換行符
默認的RS代表,輸入數據流中的每行新文本就是一條新記錄
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data3
kobe bryant
24 Los Lakers
Los, road34
99038
Paul Gaoso
15 los Lakers
Los, road 38
23123
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS="\n";RS=""} {print $1, $4}' data3
kobe bryant 99038
Paul Gaoso 23123
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS="\n";RS=""} {print $1, $2}' data3
kobe bryant 24 Los Lakers
Paul Gaoso 15 los Lakers
xcy@xcy-virtual-machine:~/shell/22zhang$
上面的例子中,4行纔是一條記錄,因此指定FS=」\n」
每行只是一個字段。
如何判斷一個新的數據行的開始:解決方法計算RS變量設爲空。而後在數據記錄之間留一個空白行。gawk會把每一個空白行當作一個記錄分隔符。
說明:
默認的字段分隔符是空格,記錄分割符是換行符
上面的例子把字段分割符改爲了換行符,記錄分隔符編程了空白行(RS=」」)
2. 數據變量
還有一些其餘的內建變量:
變量 |
描述 |
ARGC |
當前命令行參數個數 |
ARGIND |
當前文件在ARGV的位置 |
ARGV |
包含命令行參數的數組 |
CONVFMT |
數字的轉換格式,模式是%.6 g |
ENVIRON |
當前shell環境變量及其值組成的關聯數組 |
ERRNO |
當讀取或關閉文件發生錯誤時的系統錯誤號 |
FILENAME |
用做輸入數據的數據文件的文件名 |
FNR |
當前數據文件的數據行數 |
IGNORECASE |
設成非零值,忽略gawk命令中出現的字符串的字符大小寫 |
NF |
數據文件中的字段總數 |
NR |
已處理的輸入記錄數 |
OFMT |
數字的輸出格式,默認值%.6 g |
RLENGTH |
由match函數所匹配的字符串的長度 |
RSTART |
由match函數所匹配的字符串的起始位置 |
實例1:
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ARGC,ARGV[1]}' data2
2 data2
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ENVIRON["HOME"]}'
/home/xcy
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{print ENVIRON["HOME"]; print ENVIRON["PATH"]}'
/home/xcy
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/sbin/:/usr/bin:/usr/sbin:/home/xcy/Bt_A7/Bt_A7/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
xcy@xcy-virtual-machine:~/shell/22zhang$
ENVIRON[「HOME」] 從系統中提取HOME環境變量的值。
例子2:
當要在gawk程序中跟蹤數據字段和記錄時,變量FNR,NF和NR就很是方便了。
NF變量能夠在你不知道具體位置的狀況下指定記錄中的最後一個數據字段:
$gawk ‘BEGIN{FS=」:」; OFS=」:」} {print $1, $NF}’ /etc/passwd
假設NF爲7,那麼至關因而$7。打印最後一個字段
例子3:
FNR變量含有當前數據文件中已處理過的記錄數
NR變量則含有已處理過的記錄總數
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} {print $1,"FNR="FNR}' data1
data11 FNR=1
data21 FNR=2
data31 FNR=3
data41 FNR=4
data51 FNR=5
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} {print $1,"FNR="FNR, "NR="NR} END{print "There were ",NR," recordes"}' data1 data1
data11 FNR=1 NR=1
data21 FNR=2 NR=2
data31 FNR=3 NR=3
data41 FNR=4 NR=4
data51 FNR=5 NR=5
data11 FNR=1 NR=6
data21 FNR=2 NR=7
data31 FNR=3 NR=8
data41 FNR=4 NR=9
data51 FNR=5 NR=10
There were 10 recordes
xcy@xcy-virtual-machine:~/shell/22zhang$
當處理第2個文件時,FNR又被置成1了,可是NR仍是繼續增長的。
注意:
1)在shell腳本中使用gawk時,應該將gawk的命令放到不一樣的行,便於理解和閱讀
2)若是在不一樣的shell腳本中使用了相同的gawk腳本,應該把gawk放在一個單獨的文件中。再用-f參數去引用它。
變量名能夠是字母下劃線開頭,還能夠有數字。而且變量名區分大小寫
1.在腳本中給變量賦值
能夠對變量進行修改,能夠進行數學運算
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '
> BEGIN{
> test="hahaha, i am test"
> print test}'
hahaha, i am test
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '
BEGIN{
test="hahaha, i am test"
print test
> test=156
> print test
> }'
hahaha, i am test
156
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '
> BEGIN{
> x=4
> x=x*3+4
> print x
> }'
16
xcy@xcy-virtual-machine:~/shell/22zhang$
2. 在命令行上給變量賦值
也能夠用gawk命令行來給程序中的變量賦值。這容許你在正常的代碼以外賦值。
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script
BEGIN{FS=","}
{print $n}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script n=3 data1
data13
data23
data33
data43
data53
xcy@xcy-virtual-machine:~/shell/22zhang$
上面能夠給n進行賦值,改變腳本的行爲。
這樣能夠在不改變腳本代碼的狀況下就能改變腳本的行爲
上面這樣存在的問題是設置的變量在代碼的BEGIN部分不可用
解決方法,用-v參數。它容許你在BEGIN代碼以前設定變量,要放在腳本代碼以前。
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script2
BEGIN{print "The starting value is",n; FS=","}
{print $n}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -v n=4 -f script2 data1
The starting value is 4
data14
data24
data34
data44
data54
xcy@xcy-virtual-machine:~/shell/22zhang$
gawk編程語言使用關聯數組提供數組功能
關聯數組跟數字數組不一樣之處在於它的索引值能夠是任意文本字符串。
不須要用連續的數字來標識數組元素。關聯數組用各類字符串來引用值
每一個索引字符串都必須可以惟一標識賦給它的數據元素
用標準賦值語句來定義數組變量。格式以下:
var[index]=element
var是變量名,index是關聯數組的索引值 element是數據元素值
例子:
這裏要加雙引號,數字不用加,字符串須要加
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '
BEGIN{
nba["kobe"]="bryant"
nba["cp3"]="paul"
print nba["kobe"]
print nba["cp3"]
}'
bryant
paul
# 還能夠進行數學運算。
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk '
> BEGIN{
> arr[1]=99
> arr[2]=77
> total=arr[1] + arr[2]
> print "total =",total
> }'
total = 176
xcy@xcy-virtual-machine:~/shell/22zhang$
關聯數組的索引能夠是任何東西
遍歷數組能夠用for語句的一種特殊形式:
for (var in array)
{
statements
}
這個for語句會在每次循環時都將關聯數組array的下一個索引值賦值給變量var,而後執行一遍statements
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script3
BEGIN{
var["a"]="hahah"
var["b"]=2
var["c"]="yutong keche"
var["d"]=4
for (test in var)
{
print "Index:",test," - Value:",var[test]
}
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script3
Index: a - Value: hahah
Index: b - Value: 2
Index: c - Value: yutong keche
Index: d - Value: 4
xcy@xcy-virtual-machine:~/shell/22zhang$
格式以下:
delete array[index]
刪除之後就沒辦法再用它來提取元素值了。
好比:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script4
BEGIN{
var["a"]="hahah"
var["b"]=2
var["c"]="yutong keche"
for (test in var)
{
print "old: Index:",test," - Value:",var[test]
}
print "Now,delete array:"
delete var["c"]
for (test in var)
{
print "new: Index:",test," - Value:",var[test]
}
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script4
old: Index: a - Value: hahah
old: Index: b - Value: 2
old: Index: c - Value: yutong keche
Now,delete array:
new: Index: a - Value: hahah
new: Index: b - Value: 2
xcy@xcy-virtual-machine:~/shell/22zhang$
gawk支持多種類型的匹配模式來過濾數據記錄。
BEGIN和END關鍵字用來讀取數據流以前或以後執行命令的特殊模式
能夠用基礎正則表達式(BRE)或擴展正則表達式(ERE)來選擇程序腳本做用在數據流中的哪些行上。
使用正則表達式時,正則表達式必須出如今它要控制的程序腳本的左花括號前。
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script5
BEGIN{FS=","}
/11/{print $1, $2}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script5 data1
data11 data12
xcy@xcy-virtual-machine:~/shell/22zhang$
正則表達式/11/匹配了字段中含有字符串11的記錄。
匹配操做符容許將正則表達式限定在記錄中的特定數據字段。匹配操做符是~。
能夠指定匹配操做符,數據字段變量以及要匹配的正則表達式
$1 ~ /^data/
$1變量表明記錄中的第一個數據字段。
上面的例子會過濾出以data開頭的全部記錄。
取反: $1 !~ /^data1/ 匹配第一個字段不以data1開頭的記錄
例子2:
// 匹配第2個字段爲data2開頭的記錄,而且打印第1和第3個字段。$2表示第2個字段
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1
data11,data12,data13,data14
data21,data22,data23,data24
data31,data32,data33,data34
data41,data42,data43,data44
data51,data52,data53,data54
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $1, $3}' data1 data21 data23
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=","} $2 !~ /^data2/{print $1, $3}' data1 // 這裏還能夠取反,匹配第二個字段不以data2開頭的記錄。加個感嘆號
data11 data13
data31 data33
data41 data43
data51 data53
xcy@xcy-virtual-machine:~/shell/22zhang$
例子3:
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk 'BEGIN{FS=":"} $1 ~ /^xcy/{print $1,":" $NF}' /etc/passwd
xcy :/bin/bash
xcy@xcy-virtual-machine:~/shell/22zhang$
例子4:! 用來排除正則表達式中的匹配
$ gawk -F: '$1 !~ /^xcy|^root/{print $1, ":" $NF}' /etc/passwd
-F 用來指定主句字段的分隔符
上面代表過濾第一個字段不以xcy開頭,或不以root開頭。
還能夠在匹配模式中用數學表達式。
例子:想顯示全部屬於root用戶組(組ID爲0)的系統用戶
$gawk –F: ‘$4 == 0{print $1}’ /etc/passwd
還能夠用任何常見的數學比較表達式: == <= >= > <
匹配字符串:注意這時候是徹底匹配
$gawk –F, ‘$1==」data」 {print $1}’ data1
第一個字段必須是data,而不是包含data
給if語句定義一個求值的條件,並將其用圓括號括起來。
條件爲真在if後面的語句就會執行。
還能夠接上else。和C語言的差很少
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data4
3
5
34
467
1
xcy@xcy-virtual-machine:~/shell/22zhang$ cat ifscript
{
if ($1 > 29)
{
print "$1 > 29" # 多條命令須要用{}括起來
print $1
}
else if($1 == 3)
{
print "step 2 $1 == 3"
}
else
{
print "step 3 "
}
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f ifscript data4
step 2 $1 == 3
step 3
$1 > 29
34
$1 > 29
467
step 3
xcy@xcy-virtual-machine:~/shell/22zhang$
還能夠在單行上使用else子句,這樣就須要在if後面接上分號;
$ gawk '{if($1 == 3) print $1" == 3 "; else print $1,"!= 3"}' data4
基本格式:
while (condition)
{
statement
}
while裏面還能夠放break和continue。用起來跟C語言同樣
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data5
100 110 120
170 180 190
300 310 320
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script6
{
total=0
i=1
while(i < 4)
{
total += $i
i++
if(i==3)
{
break
#continue
}
print "i=", i
}
avg=total/3
print "Average:",avg
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script6 data5
i= 2
Average: 70
i= 2
Average: 116.667
i= 2
Average: 203.333
xcy@xcy-virtual-machine:~/shell/22zhang$
和while語句相似,可是會在檢查條件語句以前執行命令。格式以下:
do
{
statement
} while(condition)
這種格式保證了語句在條件被求值以前至少執行一次
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script7
{
total=0
i=1
do
{
total += $i
i++
} while(total < 300)
print "total:",total,"i=",i
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script7 data5
total: 330 i= 4
total: 350 i= 3
total: 300 i= 2
xcy@xcy-virtual-machine:~/shell/22zhang$
支持C風格的for循環:
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script8
{
total=0
for(i=1; i<4; i++)
{
total += $i
}
avg=total/3
print "Total:",total,"Average:",avg
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script8 data5
Total: 330 Average: 110
Total: 540 Average: 180
Total: 930 Average: 310
xcy@xcy-virtual-machine:~/shell/22zhang$
print打印在如何顯示數據上並未提供多少控制。
下面介紹一個格式化打印命令,printf,和C語言的那個有點相似:
printf 「format string」 ,var1,var2…
前面也是格式化命令。跟C語言很像:
1)
%c 輸出字符, %d 整數值, %i 整數值,%e 用科學計數法顯示數
%f 浮點數,%g 科學計數法或浮點數顯示(較短的)
%o 八進制,%s 字符串
%x 十六進制小寫,%X 十六進制大寫
2)
還有三種修飾符能夠用來進一步控制輸出
width:指定輸出字段最小寬度的數字值。實際比這短,則會補充空格,不然按正常輸出
prec:指定浮點數中小數點後面的位數。或者文本字符串中顯示的最大字符數
-(減號):指明在格式化空間中放入數據時採用左對齊,而不是右對齊
例子:
$ cat data3
kobe bryant
24 Los Lakers
Los, road34
99038
Paul Gaoso
15 los Lakers
Los, road 38
23123
$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%s %s\n", $1,$2}' data3 #正常輸出
kobe bryant 24 Los Lakers
Paul Gaoso 15 los Lakers
$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%16s %s\n", $1,$2}' data3 #指定輸出字段最小寬度
kobe bryant 24 Los Lakers
Paul Gaoso 15 los Lakers
$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1,$2}' data3 #指定左對齊
kobe bryant 24 Los Lakers
Paul Gaoso 15 los Lakers
還能夠指定浮點數格式
… {printf 「%5.1f\n」, avg} …
佔5位,小數點後只顯示一位。
gawk提供了很多內建的函數,能夠進行常見的數學 字符串以及時間函數運算
函數 |
描述 |
atan2(x,y) |
x/y的反正切,x y以弧度爲單位 |
cos(x) |
X的餘弦 x以弧度爲單位 |
exp(x) |
X的指數函數 |
int(x) |
X的整數部分,取靠近零一側的值 |
log(x) |
X的天然對數 |
rand(x) |
比0大比1小的隨機浮點數 |
sin(x) |
正弦,x以弧度爲單位 |
sqrt(x) |
X的平方根 |
srand(x) |
爲計算隨機數指定一個種子值 |
and(v1,v2) |
執行v1和v2的按位與運算 |
compl(val) |
執行val的補運算 |
lshift(val,count) |
Val的值左移count位 |
or(v1,v2) |
V1和v2的按位或運算 |
rshift(val,count) |
Val右移count位 |
xor(v1,v2) |
V1和v2的異或運算 |
例子:
$ gawk 'BEGIN{x=rand(); print "x =",x}'
$gawk 'BEGIN{x=int(-7.6); print "x =",x}'
$ gawk 'BEGIN{x=sin(1.57); print "x =",x}'
$ gawk 'BEGIN{x=int(10*rand()); print "x =",x}'
$ gawk 'BEGIN{x=and(1,2); print "x =",x}'
$ gawk 'BEGIN{x=lshift(1,2); print "x =",x}'
$ gawk 'BEGIN{x=xor(1,2); print "x =",x}'
函數 |
描述 |
asort(s [,d]) |
將數組s按數據元素值排序。索引值會被替換成表示新的排序順序的連續數字。另外若是指定了d,則排序後的數組會存儲在數組d中。 |
asorti(s [,d]) |
將數組s按索引值排序。生成的數組會將索引值做爲數據元素值,用連續數字因此來代表排序順序。若指定了d,排序後是數組會存在d中 |
gensub(r,s,h [,t]) |
查找變量$0或目標字符串t(若提供的話)來匹配正則表達式r。 若是h是一個以g或G開頭的字符串,就用s替換掉匹配的文本。 若是h是數字,它表示要替換掉的第h處r匹配的地方 |
gsub(r,s [,t]) |
查找變量$0或目標字符串t(若提供的話)來匹配正則表達式。 若是找到了就所有替換成字符串s |
index(s,t) |
返回字符串t在字符串s中的索引值。若是沒找到返回0 |
length([s]) |
返回字符串s的長度,若是沒有指定的話返回$0的長度 |
match(s, r [,a]) |
返回字符串s中正則表達式r出現位置的索引。若指定數組a,則會存儲s中匹配正則表達式的那部分 |
split(s, a [,r]) |
將s用FS字符或正則表達式r(若指定的話)分開放到數組a中。返回字段總數 |
sprintf(format,variables) |
用提供的format和variables返回一個相似於printf輸出的字符串 |
sub(r,s [,t]) |
在變量$0或目標字符串t中查找正則表達式t的匹配。若找到了,就用字符串s替換掉第一處匹配 |
substr[s,i [,n]] |
返回s從索引值i開始的n個字符組成的字符串。若未提供n,則返回s剩下的部分 |
tolower(s) |
所有轉小寫 |
toupper(s) |
所有轉大寫 |
有些用起來比較簡單,好比大小寫,求長度
$ gawk 'BEGIN{x=length("chong"); print "x =",x}'
$ gawk 'BEGIN{x=toupper("chong"); print "x =",x}'
下面是asort的例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script9
BEGIN{
var["a"]=177
var["b"]=9
var["c"]=3
var["d"]=4444
var["e"]=566
asort(var,test)
for (i in test)
{
print "Index:",i,"-value:",test[i]
}
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script9
Index: 4 -value: 566
Index: 5 -value: 4444
Index: 1 -value: 3
Index: 2 -value: 9
Index: 3 -value: 177
xcy@xcy-virtual-machine:~/shell/22zhang$
注意看對var數組的數據元素進行排序了。排序後的數組放在test數組裏面了。
索引值被替換成了數字。索引最大的對應數據元素也是最大的。
下面是split的例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data1
data11,data12,data13,data14
data21,data22,data23,data24
data31,data32,data33,data34
data41,data42,data43,data44
data51,data52,data53,data54
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script10
BEGIN{
FS=","
}
{
count=split($0,test)
for (i in test)
{
print "Index:", i, "-Value:",test[i]
}
print "count =",count
#print test[1], test[5]
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script10 data1
將每一行用FS字符(,)分開,放到了test數組上。再打印數組的數據。
count表示字段總數
函數 |
描述 |
mktime(datadpace) |
將一個按YYYYMMDDHHMMSS[DST]格式指定的日期轉成時間戳值 |
strftime(format [,timestamp]) |
將當前時間的時間戳或timestamp(若提供的話)轉化格式化日期(採用shell函數data()的格式) |
systime() |
返回當前時間的時間戳 |
例子:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat script11
BEGIN{
date=systime()
day=strftime("%A, %B %d, %Y",date)
print day
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script11
星期六, 十一月 25, 2017
xcy@xcy-virtual-machine:~/shell/22zhang$
注意:BEGIN後面的{要挨着BEGIN寫,不能換行寫。
不然報錯
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f script11
gawk: script11:2: BEGIN 塊必須有一個行爲部分
必需要用function關鍵字,格式以下:
function name([variables])
{
statement
}
函數名必須可以統一標識函數。能夠在調用的gawk程序中傳給這個函數一個或多個變量
例子:
// 打印記錄中的第三個字段
function printthird()
{
print $3
}
還能夠用return返回值。
例子:
function myrand(limit)
{
return int(limit * rand())
}
用法:
x=myrand(100)
定義函數時,它必須出如今全部代碼塊以前(包括BEGIN代碼塊)。
實例:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat data3
kobe bryant
24 Los Lakers
Los, road34
99038
Paul Gaoso
15 los Lakers
Los, road 38
23123
xcy@xcy-virtual-machine:~/shell/22zhang$ cat fun1
function myprint()
{
print "This is myprint() +++"
printf "%-16s - %s\n", $1,$4
}
BEGIN{
FS="\n"
RS=""
}
{
myprint()
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f fun1 data3
This is myprint() +++
kobe bryant - 99038
This is myprint() +++
Paul Gaoso - 23123
xcy@xcy-virtual-machine:~/shell/22zhang$
先格式化記錄中的第一個和第四個數據字段。再輸出
定義了函數就能夠在程序的代碼中隨便使用了
能夠將多個函數放到一個庫文件中,這樣就能在全部的gawk程序中使用了。
步驟:
1)先建立一個存儲全部gawk函數的文件
xcy@xcy-virtual-machine:~/shell/22zhang$ cat funlib
function mylib()
{
print "mylib() +++"
}
function myprint()
{
printf "%-16s - %s\n",$1,$4
}
function myrand(limit)
{
return int(limit * rand())
}
function printthird()
{
print $3
}
2)就能夠在腳本中使用啦
xcy@xcy-virtual-machine:~/shell/22zhang$ cat usefunlib
BEGIN{
FS="\n"
RS=""
}
{
myprint()
}
xcy@xcy-virtual-machine:~/shell/22zhang$ gawk -f funlib -f usefunlib data3
kobe bryant - 99038
Paul Gaoso - 23123
xcy@xcy-virtual-machine:~/shell/22zhang$
要引用文件須要使用-f參數。能夠在同一命令行中使用多個-f參數。
假設有一個數據文件,裏面有兩支隊伍每隊2我的,每人3次的比賽成績。要求總成績和平均成績:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat scores.txt
Rich Blum,team1,100,115,99
Bar Blum,team1,110,118,114
Chr Bre,team2,120,80,90
Tim Bre,team2,125,70,60
下面是腳本:
xcy@xcy-virtual-machine:~/shell/22zhang$ cat bowling.sh
#!/bin/bash
for team in $(gawk -F, '{print $2}' scores.txt | uniq)
do
# echo "team: $team"
gawk -v team=$team 'BEGIN{FS=",";total=0}
{
# print "step1+++"
if ($2==team)
{
total += $3 + $4 + $5;
}
}
END{
avg = total / 6;
print "Total for",team,"is",total,"The avgarge is",avg
}' scores.txt
done
腳本分析:
1)注意uniq這個關鍵字,這裏能夠排除同樣的。for語句是用來篩選隊名的。
2)for循環裏面,假如隊名是team1,那麼就先處理team1。會讀取全部記錄,將隊名都爲team1的記錄的$3 $4 $5相加,就是總成績了。最後求平均值
這裏是運行狀況:
xcy@xcy-virtual-machine:~/shell/22zhang$ ./bowling.sh
Total for team1 is 656 The avgarge is 109.333
Total for team2 is 545 The avgarge is 90.8333