原創:花括號MC(微信公衆號:huakuohao-mc)。關注JAVA基礎編程及大數據,注重經驗分享及我的成長。javascript
AWK
誕生於1977的貝爾實驗室,是由 Alfred Aho,Peter Weinberger和Brian Kernighan三位大神開發,AWK
的命名是由三位做者的Family Name的首字母組成。java
三位大神開發AWK
的初衷是爲了方便快速的處理文本及數據信息,在當年那個即沒有python
也沒有go
的年代,這是一個很酷也頗有意義的事情;不過話說回來,即使是如今有了Python
跟Go
,AWK
在平常線上運維方面仍然佔據一席之地,並且幾乎不可替代。python
若是你對AWK
仍是不甚瞭解,那麼但願經過這篇博文,可以讓各位作個簡單入門,若是這篇文章還能提起你學習AWK
的興趣就更好了。程序員
AWK
的程序通常都很短,但並非說AWK
寫不出邏輯複雜的程序。AWK
像你學過的其它語言同樣,支持變量自定義,數組結構,for
循環等等,同時也支持自定義函數。正則表達式
假設咱們打算處理一個在線商店的後臺日誌,內容以下:shell
python基礎教程 山治 34.50 5
python高級教程 索隆 40.00 6
python實戰 娜美 38 3
java編程思想 弗蘭克 48.00 6
Vue教程 javascript小組 55.00 8
awk基礎教程 路飛 42 3
複製代碼
第一列爲書名,第二列爲做者,第三列爲價格,第四列爲當日銷售數量。咱們將該文件命名爲awk_books.log
。接下來咱們將經過一些實際的案例需求來學習AWK
編程
找出價格大於40的書籍數組
awk '$3>40 {print $0}' awk_books.log
複製代碼
輸出:bash
$ awk '$3>40 {print $0}' awk_books.log
java編程思想 弗蘭克 48.00 6
Vue教程 javascript小組 55.00 8
awk基礎教程 路飛 42 3
複製代碼
解釋微信
awk
的意思是告訴操做系統我要執行awk
程序,請作好準備。單引號裏面的內容爲具體的程序邏輯。awk_books.log
爲要處理的文件。
寫awk
的程序其實很簡單,由於是有固定套路的。套路就是 'pattern {action}'
,pattern
稱爲模式,action
稱爲動做。
awk
會自動讀入要處理文件的每一行內容,依次用pattern
去匹配,若是匹配成功,則執行action
。對於上面的例子,pattern
爲$3>40
,action
爲{print $0}
。
注意:
pattern
跟action
沒必要同時存在,後面我會有例子給你們解釋什麼意思。
到此爲止,對於上面的小例子,除了$3
和$0
你還不理解之外,其它應該都瞭解了。
awk
會將輸入的每一行按照空白字符進行分隔,所以分隔以後的第一列就是$1
,第二列就是$2
,以此類推,咱們的例子中書價在第三列,天然就是$3
,變量$0
則表明整行記錄。
若是要處理的文本內容不是按照空白字符分隔怎麼辦?你能夠這樣處理。
echo "hello-world" | awk 'BEGIN{FS="-"} {print $1}'
複製代碼
輸出的結果都爲hello
FS
爲awk
的內置變量,表示輸入列的分隔符,默認爲空白符。上面的例子中咱們將FS
的默認值設置成咱們但願的樣子,也就是-
。除了FS
之外,跟分隔符相關的內置變量還有輸出列分隔符OFS
,輸入行分隔符RS
,輸出行分隔符ORS
。我就不依依舉例展現了。
BEGIN
表示的意思是AWK
程序開始執行以前執行BEGIN
關鍵字以後的語句,並且只執行一次,因此常常用來初始化變量或者文件頭。除了BEGIN
,還有END
,我後面還會有樣列介紹,你們不要着急。
好了,這裏先作個簡單的小結,而後繼續出發。 1.咱們知道了如何在命令行終端調用AWK
程序。 2.知道了AWK
程序的固定套路爲 'pattern {action}'
格式 3.瞭解了內置變量$0
,$1
,以及FS
的做用。
接下來經過一些具體的樣例繼續學習。
打印出每一行最後一列
awk '{print $NF}' awk_books.log
複製代碼
輸出結果:
$ awk '{print $NF}' awk_books.log
5
6
3
6
8
3
複製代碼
這個例子中,明顯沒有pattern
而只有action
。AWK
中若是沒有pattern
,則默認匹配全部行。而NF
爲AWK
的內置變量,表示每一行有多少列。因此$NF
天然就表明着最後一列的輸出內容。基於這個例子,你能夠嘗試着打印出每一行的倒數第二列內容,代碼以下:
awk '{print $(NF-1) }' awk_books.log
複製代碼
只打印出第二行內容
awk 'NR == 2' awk_books.log
複製代碼
輸出結果:
$ awk 'NR == 2' awk_books.log
python高級教程 索隆 40.00 6
複製代碼
這個例子明顯沒有action
只有pattern
,若是沒有寫action
則執行默認action
,默認的action
就是打印匹配的行內容。NR
也是內置變量,表示AWK
已經讀取的行數。
打印每一行的內容及行號
awk '{print NR,$0}' awk_books.log
複製代碼
輸出結果:
$ awk '{print NR,$0}' awk_books.log
1 python基礎教程 山治 34.50 5
2 python高級教程 索隆 40.00 6
3 python實戰 娜美 38 3
4 java編程思想 弗蘭克 48.00 6
5 Vue教程 javascript小組 55.00 8
6 awk基礎教程 路飛 42 3
複製代碼
print
裏面用逗號分隔要打印的多個內容,輸出的時候逗號會被空格替代。
更好的輸出
接上面的例子,咱們讓輸出結果更易讀一些。
awk 'BEGIN{print"編號 書名 做者 價格 銷量"; print""} {print NR,$0} END{print"";print "輸出結束!"}' awk_books.log
複製代碼
輸出結果
$ awk 'BEGIN{print"編號 書名 做者 價格 銷量"; print""} {print NR,$0} END{print"";print "輸出結束!"}' awk_books.log
編號 書名 做者 價格 銷量
1 python基礎教程 山治 34.50 5
2 python高級教程 索隆 40.00 6
3 python實戰 娜美 38 3
4 java編程思想 弗蘭克 48.00 6
5 Vue教程 javascript小組 55.00 8
6 awk基礎教程 路飛 42 3
輸出結束!
複製代碼
BEGIN
,在前面已經提到了過了,這裏是爲了加深一下你們的理解。BEGIN
和END
後面跟隨的語句都只執行一次,即在程序的開頭和結束。
打印包含Java的行
awk '/java/ {print $0}' awk_books.log
複製代碼
輸出結果:
$ awk '/java/ {print $0}' awk_books.log
java編程思想 弗蘭克 48.00 6
Vue教程 javascript小組 55.00 8
複製代碼
這個樣例的匹配模式是個正則表達式,只要有匹配的內容就會輸出對應的行。你能夠根據業務需求寫出更復雜的正則表達式。
打印第一列包含java的行
awk '$1 ~/java/ {print $0}' awk_books.log
複製代碼
輸出結果:
$ awk '$1 ~/java/ {print $0}' awk_books.log
java編程思想 弗蘭克 48.00 6
複製代碼
打印第一列不包含Java的行
awk '$1 !~/java/ {print $0}' awk_books.log
複製代碼
輸出結果:
$ awk '$1 !~/java/ {print $0}' awk_books.log
python基礎教程 山治 34.50 5
python高級教程 索隆 40.00 6
python實戰 娜美 38 3
Vue教程 javascript小組 55.00 8
awk基礎教程 路飛 42 3
複製代碼
統計輸入文本的總行數
awk 'END {print NR}' awk_books.log
複製代碼
輸出結果:
$ awk 'END {print NR}' awk_books.log
6
複製代碼
輸出字符數超過33的行
awk 'length($0)> 33' awk_books.log
複製代碼
輸出結果:
$ awk 'length($0)> 33' awk_books.log
java編程思想 弗蘭克 48.00 6
Vue教程 javascript小組 55.00 8
複製代碼
length
爲內置函數,此外還有不少內置函數,不在此一一列舉了,感興趣的能夠去查。
輸出價格最高的行
awk '$3>max {max = $3; maxline=$0} END {print max,maxline}' awk_books.log
複製代碼
輸出結果:
$ awk '$3>max {max = $3; maxline=$0} END {print max,maxline}' awk_books.log
55.00 Vue教程 javascript小組 55.00 8
複製代碼
這裏max
及maxline
爲自定義變量,AWK
裏面的變量不用事先聲明,直接用就OK,默認值爲空或者0。
計算當天銷售總價並輸出
awk '{total += $3*$4} END { print total}' awk_books.log
複製代碼
輸出結果:
$ awk '{total += $3*$4} END { print total}' awk_books.log
1380.5
複製代碼
找出全部Python的書目,而後按照價格排序
awk '$1 ~/python/ {print $0}' awk_books.log|sort -n -k 3 -t ' '
複製代碼
輸出結果:
$ awk '$1 ~/python/ {print $0}' awk_books.log|sort -n -k 3 -t ' '
python基礎教程 山治 34.50 5
python實戰 娜美 38 3
python高級教程 索隆 40.00 6
複製代碼
找出全部Python的書目,按照價格排序,並輸出價格最高的兩條
awk '$1 ~/python/ {print $0}' awk_books.log|sort -r -n -k 3 -t ' '|head -n 2
複製代碼
輸出結果:
$ awk '$1 ~/python/ {print $0}' awk_books.log|sort -r -n -k 3 -t ' '|head -n 2
python高級教程 索隆 40.00 6
python實戰 娜美 38 3
複製代碼
最後兩個列子借住了sort
和head
,不瞭解兩個指令的能夠去查一下,這裏不作過多的介紹了。
好了,以上這些AWK
知識應該夠各位應付平常的工做需求了。若是還不夠怎麼辦呢?去買兩本書,繼續深刻學啊!
推薦閱讀:
·END·
Java·大數據·我的成長