1、介紹
? ? ? ? awk是一種編程語言,用于在linux/unix下對文本和數據進行處理。數據可以來自標準輸入(stdin)、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更多是作為腳本來使用。awk有很多內建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢
2、語法
awk [options] 'script' var=value?file(s)
awk [options] -f scriptfile var=value file(s)
-F?fs ??fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:
-v?var=value ??賦值一個用戶定義變量,將外部變量傳遞給awk
-f?scripfile ?從腳本文件中讀取awk命令
-m[fr]?val ??對val值設置內在限制,-mf選項限制分配給val的最大塊數目;-mr選項限制記錄的最大數目
2、awk工作原理
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
第一步:執行BEGIN{ commands }語句塊中的語句;
第二步:從文件或標準輸入(stdin)讀取一行,然后執行pattern{ commands }語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
第三步:當讀至輸入流末尾時,執行END{ commands }語句塊。
3、使用
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3
cat a.js
1
2
3
awk 'BEGIN{print "start"} {a+=$1} END{print a}' b.js
start
6
4、內置變量
說明:[A][N][P][G]表示第一個支持變量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
$n 當前記錄的第n個字段,比如n為1表示第一個字段,n為2表示第二個字段。
$0 這個變量包含執行過程中當前行的文本內容。
[N] ARGC 命令行參數的數目。
[G] ARGIND 命令行中當前文件的位置(從0開始算)。
[N] ARGV 包含命令行參數的數組。
[G] CONVFMT 數字轉換格式(默認值為%.6g)。
[P] ENVIRON 環境變量關聯數組。
[N] ERRNO 最后一個系統錯誤的描述。
[G] FIELDWIDTHS 字段寬度列表(用空格鍵分隔)。
[A] FILENAME 當前輸入文件的名。
[P] FNR 同NR,但相對于當前文件。
[A] FS 字段分隔符(默認是任何空格)。
[G] IGNORECASE 如果為真,則進行忽略大小寫的匹配。
[A] NF 表示字段數,在執行過程中對應于當前的字段數。
[A] NR 表示記錄數,在執行過程中對應于當前的行號。
[A] OFMT 數字的輸出格式(默認值是%.6g)。
[A] OFS 輸出字段分隔符(默認值是一個空格)。
[A] ORS 輸出記錄分隔符(默認值是一個換行符)。
[A] RS 記錄分隔符(默認是一個換行符)。
[N] RSTART 由match函數所匹配的字符串的第一個位置。
[N] RLENGTH 由match函數所匹配的字符串的長度。
[N] SUBSEP 數組下標分隔符(默認值是34)。
1)每行的最后一個值
echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $NF}'
f3
f5
echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $(NF-1)}'
f2
f4
2)每行的列數
echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print NF}'
3
3
3)傳遞參數
VAR=10000
echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'
5、運算和判斷
awk 'BEGIN{a="b";print a++,++a;}'
0 2
awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print (a in arr);}'
1
注意:所有用作算術運算符進行操作,操作數自動轉為數值,所有非數值都變為0
awk 'BEGIN{
????test=100;
????if(test>90){
????????print "very good";
????} else if(test>60){
????????print "good";
????} else{
????????print "no pass";
????}
}'
very good
awk 'BEGIN{
for(k in ENVIRON){
print k"="ENVIRON[k];
}
}'
TERM=linuxG_BROKEN_FILENAMES=1SHLVL=1
pwd=/root/text...
logname=root
HOME=/root
SSH_CLIENT=192.168.1.21 53087 22
6、高級輸入
cat a.js
a
b
c
d
e
awk 'NR%2==1{next}{print NR,$0;}' a.js
2 b
4 d
cat a.js:
web01[192.168.2.100]
httpd ok
tomcat ok
sendmail ok
web02[192.168.2.101]
httpd ok
postfix ok
web03[192.168.2.102]
mysqld ok
httpd ok
awk '/^web/{T=$0;next;}{print T":\t"$0;}' a.js
web01[192.168.2.100]: httpd okweb01[192.168.2.100]: tomcat okweb01[192.168.2.100]: sendmail okweb02[192.168.2.101]: httpd okweb02[192.168.2.101]: postfix okweb03[192.168.2.102]: mysqld okweb03[192.168.2.102]: httpd ok
執行shell的date命令,并通過管道輸出給getline,然后getline從管道中讀取并將輸入賦值給out,split函數把變量out轉化成數組mon,然后打印數組mon的第二個元素
awk 'BEGIN{ "date" | getline out; split(out,mon); print mon[1] }' test
2018年
awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
2 is
3 a
4 test
1 it
awk 'BEGIN{OFMT="%.3f";fs=sin(1);fe=exp(10);fl=log(10);fi=int(3.1415);print fs,fe,fl,fi;}'0.841 22026.466 2.303 3