Awk這件上古神兵你會用了嗎

原創:花括號MC(微信公衆號:huakuohao-mc)。關注JAVA基礎編程及大數據,注重經驗分享及我的成長。javascript

AWK誕生於1977的貝爾實驗室,是由 Alfred Aho,Peter Weinberger和Brian Kernighan三位大神開發,AWK的命名是由三位做者的Family Name的首字母組成。java

三位大神開發AWK的初衷是爲了方便快速的處理文本及數據信息,在當年那個即沒有python也沒有go的年代,這是一個很酷也頗有意義的事情;不過話說回來,即使是如今有了PythonGoAWK在平常線上運維方面仍然佔據一席之地,並且幾乎不可替代。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}

注意: patternaction沒必要同時存在,後面我會有例子給你們解釋什麼意思。

到此爲止,對於上面的小例子,除了$3$0你還不理解之外,其它應該都瞭解了。

awk會將輸入的每一行按照空白字符進行分隔,所以分隔以後的第一列就是$1,第二列就是$2,以此類推,咱們的例子中書價在第三列,天然就是$3,變量$0則表明整行記錄。

若是要處理的文本內容不是按照空白字符分隔怎麼辦?你能夠這樣處理。

echo "hello-world" | awk 'BEGIN{FS="-"} {print $1}'
複製代碼

輸出的結果都爲hello

FSawk的內置變量,表示輸入列的分隔符,默認爲空白符。上面的例子中咱們將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 而只有actionAWK中若是沒有pattern,則默認匹配全部行。而NFAWK的內置變量,表示每一行有多少列。因此$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,在前面已經提到了過了,這裏是爲了加深一下你們的理解。BEGINEND後面跟隨的語句都只執行一次,即在程序的開頭和結束。

打印包含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
複製代碼

這裏maxmaxline爲自定義變量,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
複製代碼

最後兩個列子借住了sorthead,不瞭解兩個指令的能夠去查一下,這裏不作過多的介紹了。

好了,以上這些AWK知識應該夠各位應付平常的工做需求了。若是還不夠怎麼辦呢?去買兩本書,繼續深刻學啊!


推薦閱讀:

做爲一個程序員,你應該知道的編碼知識

Shell編程裏面的奇葩字符

Javaer運維指令合集(快餐版)

·END·
 

花括號MC

Java·大數據·我的成長

微信號:huakuohao-mc
相關文章
相關標籤/搜索