awk入門

awk是一門模式匹配的編程語言,因爲它的主要功能是用於匹配文本並處理,同時它有一些編程語言纔有的語法,例如函數、分支循環語句、變量等等,當然比起我們常見的編程語言,Awk相對比較簡單。

是一種編程語言,對文本和數據進行處理。數據可以來自標準輸入、一個或多個文件,或其它命令的輸出(即管道)。它支持用戶自定義函數和 動態正則表達式等先進功能。處理方式是 逐行掃描文件,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行操作。如果沒有指定處理動作,則把匹配的行顯示到標準輸出 (屏幕),即默認處理動作是print;如果沒有指定模式,則所有被操作所指定的行都被處理,即默認指定模式是全部。

AWK取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符

像shell一樣,awk也有好幾種,常見的如awk、nawk、mawk、gawk,

語法


awk [選項參數] 'script(awk腳本)' var=value file(s)
或
awk [選項參數] -f scriptfile var=value file(s)

參數:

-F ERE:定義字段分隔符,該選項的值可以是擴展的正則表達式(ERE):如 awk -F: ‘{print}’ test.txt 或者awk -F’:’ ‘{print}’ test.txt或者 awk -F’[:]’ ‘{print}’ test.txt

-f progfile:指定awk腳本,可以同時指定多個腳本,它們會按照在命令行中出現的順序連接在一起;

-v assignment:定義awk變量,形式同awk中的變量賦值,即name=value,賦值發生在awk處理文本之前;變量名爲關鍵字則報錯

一段awk腳本是由多個’pattern { action }’序列組成的。action是一個或者多個語句,它在輸入行匹配pattern的時候被執行。如果pattern爲空,表明這個action會在每一行處理時都會被執行。

BEGIN語句塊在程序開始執行,只執行一次 BEGIN{} - BODY語句塊對每一行執行 /patern/{} - END語句塊程序最後執行,執行一次 END{}


awk -v var=1 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' test.txt
awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' var=1 test.txt
awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' test.txt var=1
awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' test.txt var=1 test2.txt

–dump-variables [=file]:輸出排序好的全局變量列表和他們最終的值到文件中默認文件是awkvars.out

[root@VM_0_9_centos zhimin.xu]# awk --dump-variables ''
[root@VM_0_9_centos zhimin.xu]# cat awkvars.out
ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
IGNORECASE: 0
LINT: 0
NF: 0
NR: 0
OFMT: "%.6g"
OFS: " "
ORS: "\n"
RLENGTH: 0
RS: "\n"
RSTART: 0
RT: ""
SUBSEP: "\034"
TEXTDOMAIN: "messages"
[root@VM_0_9_centos zhimin.xu]#

awk –help :不做介紹

–lint[=fatal]選項: 允許檢查程序的不兼容性或者模棱兩可的代碼,當提供參數 fatal的時候,它會對待Warning消息作爲Error。
awk ‘BEGIN {LINT = 1; a}’

–posix 選項 : 該選項開啓嚴格的POSIX兼容。

–profile[=file]選項: 該選項會輸出一份格式化之後的程序到文件中,默認文件是 awkprof.out。

                                        awk --profile 'BEGIN{printf"---|Header|--\n"} {print} END{printf"---|Footer|---\n"}' marks.txt > /dev/null 

                                        cat awkprof.out

8個內建變量:Awk將一個文本文件視爲一個文本數據庫,因此它也有記錄和字段的概念。
假如有以下文件爲例

[root@VM_0_9_centos zhimin.xu]# awk '{print $0} ' test.txt
tom 1413101-12 78 76 69
cat 1267102-22 30 45 80
jack 1306123-08 66 77 88
aid 1511122-30 77 88 50
alice 1211102-20 88 99 95
tiger 1314104-11 34 45 56
[root@VM_0_9_centos zhimin.xu]#

1.FS(Field Separator) 字段分隔符, 默認按 空格 分隔爲字段變量, 1, 2…等,NF, (NF-1)表示倒數第二個($0表示整行記錄)。FS可以是任意的字符串或者正則表達式,如-F。如果沒有Sn則輸出空,不會報錯

OFS(Output Field Separator) ,   默認以 空格 字符作爲輸出分隔符的

NF(Number for Field)表示的是,一條記錄的(以FS分隔)字段的數目

[root@VM_0_9_centos zhimin.xu]# awk -F'[ -]' 'BEGIN{OFS="*";}{print NF,$1,$2,$3}' test.txt
6*tom*1413101*12
6*cat*1267102*22
6*jack*1306123*08
6*aid*1511122*30
6*alice*1211102*20
6*tiger*1314104*11
[root@VM_0_9_centos zhimin.xu]# awk 'BEGIN{OFS=":";FS=" "}{print NF,$1,$2}' test.txt
5:tom:1413101-12
5:cat:1267102-22
5:jack:1306123-08
5:aid:1511122-30
5:alice:1211102-20
5:tiger:1314104-11

awk ‘BEGIN{OFS=”_”;FS=”-“}{print 1, 2}’ test.txt <==> awk ‘BEGIN{FS=”-“}{print 1,"", 2}’ test.txt
2.RS(Record Separator)記錄分隔符。讀取文件時,默認將一行作爲一條記錄。

ORS:(Output Record Separator),每條記錄在輸出時候會用分隔符隔開,

[root@VM_0_9_centos zhimin.xu]# awk 'BEGIN{RS="\n";ORS="|"}{print $1,$2,$3}' test.txt
tom 1413101-12 78|cat 1267102-22 30|jack 1306123-08 66|aid 1511122-30 77|alice 1211102-20 88|tiger 1314104-11 34|[root@VM_0_9_centos zhimin.xu]#

NR(Number of Record) 表示的是已經讀過的總記錄數目,或者說行號(不一定是一個文件,可能是多個)。

FNR(File Number of Record) 表示的是當前文件讀過的總記錄數目,即行數

FILENAME表示當前正在輸入的文件的名字。 AWK 可以接受讀取很多個文件去處理。

[root@VM_0_9_centos zhimin.xu]# awk 'BEGIN{print "FILENAME  NR  FNR  NF  message";OFS=" | "}{print FILENAME,NR,FNR,NF,$0}' test.txt test2.txt
FILENAME  NR  FNR  NF  message
test.txt | 1 | 1 | 5 | tom 1413101-12 78 76 69
test.txt | 2 | 2 | 5 | cat 1267102-22 30 45 80
test.txt | 3 | 3 | 5 | jack 1306123-08 66 77 88
test.txt | 4 | 4 | 5 | aid 1511122-30 77 88 50
test.txt | 5 | 5 | 5 | alice 1211102-20 88 99 95
test.txt | 6 | 6 | 5 | tiger 1314104-11 34 45 56  
test2.txt | 7 | 1 | 6 | tom 1413101-12 78 76 69 523452
test2.txt | 8 | 2 | 9 | cat 1267102-22 30 45 80  23 23 234 234
test2.txt | 9 | 3 | 9 | jack 1306123-08 66 77 88 234 23 2 dssds
test2.txt | 10 | 4 | 8 | aid 1511122-30 77 88 50 sf 34 134
test2.txt | 11 | 5 | 5 | alice 1211102-20 88 99 95
test2.txt | 12 | 6 | 6 | tiger 1314104-11 34 45 5614 14
[root@VM_0_9_centos zhimin.xu]#

函數-內建函數(部分)+用戶自定義函數
close(expr):關閉管道文件
getline 該命令讓awk讀取下一行內容


[root@VM_0_9_centos zhimin.xu]# cat test.txt
tom 1413101-12 78 76 69
cat 1267102-22 30 45 80
jack 1306123-08 66 77 88
aid 1511122-30 77 88 50
alice 1211102-20 88 99 95
tiger 1314104-11 34 45 5
[root@VM_0_9_centos zhimin.xu]# awk '{getline; print $0}' test.txt
cat 1267102-22 30 45 80
aid 1511122-30 77 88 50
tiger 1314104-11 34 45 5

自定義函數

[root@VM_0_9_centos zhimin.xu]# awk -v a=1 -v b=5 'function sumTest(x,y){return x+y}BEGIN {print a,"+",b,"=",sumTest(a,b);}'
1 + 5 = 6

輸出重定向
1.重定向操作符:跟在print和printf函數的後面。>用於將輸出寫入到指定的文件中,如果文件中有內容則覆蓋,而>>則爲追加模式寫入。

                        awk 'BEGIN { print "Hello, World !!!" >> " a.txt" }'

2.管道:

實例
計算某一ip 請求 接口次數


[[email protected] /home/q/www/monitoring.qunar.com/logs]$ awk '{a[$1]++} END {for(i in a) print i,"--",a[i]}' access.2018-04-24.log
10.88.77.10 -- 2696
10.88.77.130 -- 2845
10.88.77.11 -- 2701
10.95.17.229 -- 33
10.86.236.67 -- 39
10.88.77.131 -- 2715
10.86.236.68 -- 50
10.88.77.132 -- 2651
10.88.105.196 -- 280
10.88.77.133 -- 2769
10.88.105.197 -- 344
10.88.77.134 -- 2625
10.88.77.135 -- 2694
10.88.192.132 -- 2869
10.95.22.4 -- 2641
10.88.192.133 -- 2884
.....

打印超過10個字符的行


[root@VM_0_9_centos zhimin.xu]# awk 'length>23' test.txt
jack 1306123-08 66 77 88
alice 1211102-20 88 99 95
tiger 1314104-11 34 45 5
[root@VM_0_9_centos zhimin.xu]# awk 'length($0)>23' test.txt
jack 1306123-08 66 77 88
alice 1211102-20 88 99 95
tiger 1314104-11 34 45 5

按連接數查看客戶端IP

netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章