linux shell 腳本攻略學習20--awk命令入門詳解

awk生於1977年,創始人有三個,分別爲 Alfred AhoPeter Weinberger, 和 Brian Kernighan,名稱源於三個創始人的姓的首字母。
php

做用:處理文本文件。

awk的特點是能夠對行和列進行操做,輸入man awk能夠查看awk手冊,下面將主要以例子來學習awk語言。html

語法:

mawk [-W option] [-F value] [-v var=value] [--] 'program text' [file ...]
mawk [-W option] [-F value] [-v var=value] [-f program-file] [--] [file ...]

參數-實例:

1、初識awk

截取top命令部份內容,拷貝到test.txt裏:linux

amosli@amosli-pc:~/learn/awk$ cat test.txt 
 1067 root      20   0  200m  49m  11m S    2  1.3   4:43.91 Xorg               
 3009 amosli    20   0  534m  21m  12m S    1  0.5   0:14.75 gnome-terminal     
 1002 mongodb   20   0  623m  15m 4728 S    1  0.4   0:41.17 mongod             
 2412 amosli    20   0 1005m 125m  17m S    1  3.2   0:48.61 chrome             
 3775 root      20   0     0    0    0 S    1  0.0   0:00.98 kworker/0:0        
 3829 amosli    20   0 17344 1356  952 R    1  0.0   0:00.11 top                
 2102 amosli    20   0  686m 8280 3508 S    0  0.2   0:10.11 hud-service        
 2176 amosli    20   0  419m  10m 8448 S    0  0.3   0:00.11 telepathy-indic    
 3621 root      20   0     0    0    0 S    0  0.0   0:03.30 kworker/1:2        
    1 root      20   0 24580 2524 1336 S    0  0.1   0:00.70 init               
    2 root      20   0     0    0    0 S    0  0.0   0:00.00 kthreadd           
    3 root      20   0     0    0    0 S    0  0.0   0:00.92 ksoftirqd/0        
    6 root      RT   0     0    0    0 S    0  0.0   0:01.13 migration/0        
    7 root      RT   0     0    0    0 S    0  0.0   0:00.14 watchdog/0         
    8 root      RT   0     0    0    0 S    0  0.0   0:02.16 migration/0

下面打印第2列的內容,注意pattern裏是單引號.mongodb

amosli@amosli-pc:~/learn/awk$ awk '{print $2}' test.txt 
root
amosli
mongodb
amosli
root
amosli
amosli
amosli
root
root
root
root
root
root
root

$0表示打印出來所有,$n,n>0時表示打印第n列。chrome

2、拆解awk語句塊

先看例子:shell

amosli@amosli-pc:~/learn/awk$ awk 'BEGIN { i=0 } {i++} END { print i } ' test.txt 
15

ok,是否是用點不太懂?看不太懂不要緊,下面拆解開來,一個awk腳本一般分爲3部分:BEGIN 語句塊END語句塊和可以使用模式匹配的通用語句塊。這三個部分是可選的,它們中的任何一個部分均可以不出如今腳本中。腳本一般包含在單引號或者雙引號裏。其通用模式結構以下所示:編程

awk ' BEGIN { print "start" }  pattern { commands } END { print "end" }' file

下面是實際經常使用的語法格式:函數

awk 'BEGIN { statements } { statements }  END { end statements }'  filename  

awk的工做原理:學習

(1)、執行BEGIN { commands }語句塊中的語句。this

(2)、從文件或stdin中讀取一行,而後執行pattern { commands }。重複這個過程,直到文件所有被讀取完畢。

(3)、當讀至輸入流(input stream)末尾時,執行END { commands } 語句塊。

BEGIN語句塊在awk開始從輸入流中讀取行以前被執行。這是一個可選的語句塊。

END語句塊在awk從輸入流中讀取完全部的行以後即被執行。這個一樣是可選的。

最重要的部分就是pattern語句塊中的通用命令。這個一樣是可選的。若是不提供該語句塊,則默認執行的是{ print },即打印每個讀取到的行。awk對於讀取到的每一行,都會執行這個語句塊.例:

amosli@amosli-pc:~/learn/awk$ echo -e "line1\nline2" | awk 'BEGIN { print "now start" } { print } END { print "this is end" } '
now start
line1
line2
this is end

這裏首先執行的是BEGIN { print "now start" },而後開始執行默認打印line1\nline2 ,最後讀完全部的行以後開始執行END語句塊{ print "this is end "} 

一樣能夠將BEGIN和END都去掉,只使用默認的打印方式:

amosli@amosli-pc:~/learn/awk$ echo -e "line1\nline2" | awk '{ print }' 
line1
line2

這種方式和例1的方式則是相同的。學完這兩個例子,基本上就明白了awk到底咋用的了,其格式應該是什麼樣,即已經入門了。

3、關於print

這裏的print和C語言中的基本上差異不大,但C語言我早已經忘的差很少了。仍是來看看awk裏的print是怎麼使用的吧?

有兩點須要注意:

1、當print的參數是以逗號進行分隔時,參數打印時則以空格做爲定界符。

二、在awk 的print語句中,雙引號是被當作拼接操做符的(concatenation operator) ,因此模式匹配最外層儘可能使用單引號.

關於1,舉例說明:

amosli@amosli-pc:~/learn/awk$ echo | awk ' { var1="v1";var2="v2"; print var1,var2 } '
v1 v2

這裏print var1,var2用的是逗號進行分隔的,因此打印時是以空格做爲定界符的。那若是不以逗號進行分隔呢?

amosli@amosli-pc:~/learn/awk$ echo | awk ' { var1="v1";var2="v2"; print var1 var2 } '
v1v2

打印的時候v1v2貼到一塊去了。若是再用其它符號進行分隔,打印會出錯(我試了| : \ /)。

關於2,舉例說明:

amosli@amosli-pc:~/learn/awk$ echo | awk ' { var1="v1";var2="v2"; print var1"+" var2 } '
v1+v2

這裏使用了"+",雙引號果真起到了鏈接的做用。

 

4、特殊變量

NR:表示記錄數量(number of  records),表示當前行號,和cat命令中-n 意思同樣。

NF:表示字段數量(number of fields),表示當前行的字段數量

$0,$1,$2,$n.... 前面已經說過,$0表示輸出全部文本內容,$n表示第n行數據。

舉例說明NR和NF:

下面是NF 

amosli@amosli-pc:~/learn/awk$ cat test.txt | awk '{ print NF }'
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12

每一行都有12個字段,"1067 root      20   0  200m  49m  11m S    2  1.3   4:43.91 Xorg",這裏字段的定義不是字母數量,而是由空格隔開產生的一列爲一個字段,

也能夠理解爲列數;

下面是NR:

amosli@amosli-pc:~/learn/awk$ cat test.txt | awk '{ print NR }'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

一共有15行。

5、將外部變量值傳遞給awk,-v參數

amosli@amosli-pc:~/learn/awk$ var=99;
amosli@amosli-pc:~/learn/awk$ echo | awk -v vr=$var '{ print vr }'
99

首先,定義一個var變量,賦值99;而後,將var變量的值在外部再賦給vr;最後打印出vr。

其實就是借值傳值。可是當要傳遞不少參數時就蛋疼了,太麻煩了。下面介紹一個相對簡便的方法進行外部傳值。

amosli@amosli-pc:~/learn/awk$ echo | awk  '{ print y1,y2 }' y1=$v1 y2=$v2 1 2

這裏沒有使用-v參數,只是將y1=$v1傳值放到後面去了,其實就是將y1=$v1 y2=$v2 當成file了 相似 awk '{print }' file。

6、使用awk進行過濾

1)只顯示前四行,行數小於5,和head test.txt -n 4 效果同樣。

amosli@amosli-pc:~/learn/awk$ awk  'NR<5' test.txt 
 1067 root      20   0  200m  49m  11m S    2  1.3   4:43.91 Xorg               
 3009 amosli    20   0  534m  21m  12m S    1  0.5   0:14.75 gnome-terminal     
 1002 mongodb   20   0  623m  15m 4728 S    1  0.4   0:41.17 mongod             
 2412 amosli    20   0 1005m 125m  17m S    1  3.2   0:48.61 chrome 

2)只顯示3-5行內容.

amosli@amosli-pc:~/learn/awk$ awk  'NR==3,NR==5' test.txt 
 1002 mongodb   20   0  623m  15m 4728 S    1  0.4   0:41.17 mongod             
 2412 amosli    20   0 1005m 125m  17m S    1  3.2   0:48.61 chrome             
 3775 root      20   0     0    0    0 S    1  0.0   0:00.98 kworker/0:0   

3)只顯示包含amos的行

amosli@amosli-pc:~/learn/awk$ awk '/amos/' test.txt 
 3009 amosli    20   0  534m  21m  12m S    1  0.5   0:14.75 gnome-terminal     
 2412 amosli    20   0 1005m 125m  17m S    1  3.2   0:48.61 chrome             
 3829 amosli    20   0 17344 1356  952 R    1  0.0   0:00.11 top                
 2102 amosli    20   0  686m 8280 3508 S    0  0.2   0:10.11 hud-service        
 2176 amosli    20   0  419m  10m 8448 S    0  0.3   0:00.11 telepathy-indic 

7、awk的內建函數

toupper(string),將字符串轉爲大寫

amosli@amosli-pc:~/learn/awk$ awk ' { print toupper("yes") }' 

YES
length,長度
amosli@amosli-pc:~/learn/awk$ awk ' { print length }' test.txt 80
80
80
80
80
80
80
80
80
80
80
80
80
80
72

sqrt()取平方根

amosli@amosli-pc:~/learn/awk$ awk '{ print sqrt(4)}'

2

awk的功能很是強大,知識點也很是多,網上資料也很是多,這裏主要學習的是linux shell腳本攻略第1版內容,awk的內容還須要更進一步的學習!

 

總結下: 這將是近半個月來linux學習的最後一篇文章了,shell腳本入門容易,可是,學過就忘,抽空必定要將這20篇內容再回顧一遍。shell功能很是強大,主要在於命令太多,靈活性較高,每一個命令都有不少地方去深究。想要真正掌握所學命令那就是反覆的用,不用,學了也沒意義了。個人編程最大的心得就是實踐,動手實踐,人都是眼高手低,必定要多動手!

 

awk進一步學習參考資料:

     1、awk學習筆記

     2、awk英文文檔

     3、awk簡明教程

     4、linux經常使用命令全集

     5、linux shell腳本攻略pdf(中文版下載)

相關文章
相關標籤/搜索