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


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

作用:處理文本文件。

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

語法:

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里:

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里是單引號.

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列。

2、拆解awk語句塊

先看例子:

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 }語句塊中的語句。

(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的參數是以逗號進行分隔時,參數打印時則以空格作為定界符。

2、在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(中文版下載)

     

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM