posts - 19, comments - 53, trackbacks - 0, articles - 283
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          awk使用

          Posted on 2009-11-29 11:53 Gavin.lee 閱讀(274) 評(píng)論(0)  編輯  收藏 所屬分類: Linux command

           


          調(diào)用awk有三種方式調(diào)用awk,第一種是命令行方式,如:
          Shell代碼
          1. awk [-F field-separator] 'commands' input-file(s)  

          這里,commands是真正的awk命令。上面例子中,-F域分隔符]是可選的,因?yàn)閍 w k使用空格作為缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個(gè)選項(xiàng),但如果要瀏覽諸如 passwd文件,此文件各域以冒號(hào)作為分隔符,則必須指明- F選項(xiàng):
          Shell代碼
          1. awk -F: 'commands' input-file  
          第二種方法是將所有a w k命令插入一個(gè)文件,并使 a w k程序可執(zhí)行,然后用a w k命令解釋器作為腳本的首行,以便通過鍵入腳本名稱來調(diào)用它。
          第三種方式是將所有的awk命令插入一個(gè)單獨(dú)文件,然后調(diào)用:
          Shell代碼
          1. awk -f awk_script_ file input_file(s)  
          - f選項(xiàng)指明在文件awk_script_ file中的a w k腳本,input_file(s)是使用awk進(jìn)行瀏覽的文件名。

          模式和動(dòng)作
          任何awk語句都由模式和動(dòng)作組成。在一個(gè)awk腳本中可能有許多語句。模式部分決定動(dòng)作語句何時(shí)觸發(fā)及觸發(fā)事件。處理即對(duì)數(shù)據(jù)進(jìn)行的操作。如果省略模式部分,動(dòng)作將時(shí)刻保持執(zhí)行狀態(tài)。模式可以是任何條件語句或復(fù)合語句或正則表達(dá)式。模式包括兩個(gè)特殊字段BEGIN和END。使用BEGIN語句設(shè)置計(jì)數(shù)和打印頭。BEGIN語句使用在任何文本瀏覽動(dòng)作之前,之后文本瀏覽動(dòng)作依據(jù)輸入文件開始執(zhí)行。 END語句用來在awk完成文本瀏覽動(dòng)作后打印輸出文本總數(shù)和結(jié)尾狀態(tài)標(biāo)志。如果不特別指明模式, awk總是匹配或打印行數(shù)。實(shí)際動(dòng)作在大括號(hào){ }內(nèi)指明。動(dòng)作大多數(shù)用來打印,但是還有些更長(zhǎng)的代碼諸如 if和循環(huán)(looping)語句及循環(huán)退出結(jié)構(gòu)。如果不指明采取動(dòng)作, awk將打印出所有瀏覽出來的記錄。

          域和記錄
          awk執(zhí)行時(shí),其瀏覽域標(biāo)記為$1,$2 . . . $n。這種方法稱為域標(biāo)識(shí)。使用這些域標(biāo)識(shí)將更容易對(duì)域進(jìn)行進(jìn)一步處理。使用$1,$3表示參照第1和第3域,注意這里用逗號(hào)做域分隔。如果希望打印一個(gè)有5個(gè)域的記錄的所有域,不必指明 $1,$2,$3,$4 ,$5,可使用$0,意即所有域。awk瀏覽時(shí),到達(dá)一新行,即假定到達(dá)包含域的記錄末尾,然后執(zhí)行新記錄下一行的讀動(dòng)作,并重新設(shè)置域分隔。注意執(zhí)行時(shí)不要混淆符號(hào)$和shell提示符$,它們是不同的。

          打印所有域的信息
          Shell代碼
          1. /home/l/g/tomotoboy >who   
          2. liuzk423   pts/6        Jul 20 08:27    (219.245.104.240)   
          3. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)   
          4. liuqingaihn   pts/21       Aug  7 23:10 (116.29.229.116)   
          5. guise      pts/35       Aug  7 21:13    (58.41.162.27)   
          6. uyty       pts/38       Aug  7 22:09    (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          7. yagamil    pts/46       Aug  7 20:48    (199.40.206.191)   
          8. /home/l/g/tomotoboy >who | awk '{print $0}'  
          9. liuzk423   pts/6        Jul 20 08:27    (219.245.104.240)   
          10. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)   
          11. liuqingaihn   pts/21       Aug  7 23:10 (116.29.229.116)   
          12. guise      pts/35       Aug  7 21:13    (58.41.162.27)   
          13. uyty       pts/38       Aug  7 22:09    (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          14. yagamil    pts/46       Aug  7 20:48    (199.40.206.191)  


          抽取第一域,并打印出來:
          Shell代碼
          1. /home/l/g/tomotoboy >who|awk '{print $1}'  
          2. liuzk423   
          3. tomotoboy   
          4. liuqingaihn   
          5. guise   
          6. uyty   
          7. yagamil  


          打印第一域、第三域
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk '{print $1"\t"$3}'  
          2. liuzk423        Jul   
          3. tomotoboy       Aug   
          4. liuqingaihn     Aug   
          5. guise           Aug   
          6. uyty            Aug   
          7. yagamil         Aug  


          打印信息頭和信息尾
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  'BEGIN {print "--------BEGIN-------\n"} {print $1"\t"$3} END {print "----------END-------"}'  
          2. --------BEGIN-------   
          3.   
          4. liuzk423        Jul   
          5. tomotoboy       Aug   
          6. liuqingaihn     Aug   
          7. guise   Aug   
          8. uyty    Aug   
          9. kenhq   Aug   
          10. yagamil Aug   
          11. ----------END-------  


          如果第一個(gè)域等于tomotoboy
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '{if ($1~/tomotoboy/) print $0}'  
          2. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)  


          如果行的域中包含tomotoboy就打印它
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '$0 ~/tomotoboy/'  
          2. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)  


          不匹配
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '{if ($1!~/tomotoboy/) print $0}'  
          2. liuzk423   pts/6        Jul 20 08:27    (219.245.104.240)   
          3. uyty       pts/38       Aug  7 22:09    (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          4. kenhq      pts/40       Aug  7 23:46    (116.77.50.7)   
          5. yagamil    pts/46       Aug  7 20:48    (199.40.206.191)   
          6.   
          7. /home/l/g/tomotoboy >who | awk  '$0  !~/tomotoboy/'  
          8. liuzk423   pts/6        Jul 20 08:27    (219.245.104.240)   
          9. liuqingaihn   pts/21       Aug  7 23:54 (116.29.229.116)   
          10. uyty       pts/38       Aug  7 22:09    (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          11. kenhq      pts/40       Aug  7 23:46    (116.77.50.7)   
          12. yagamil    pts/46       Aug  7 20:48    (199.40.206.191)  


          行首
          打印行首包含to的行
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '/^to/'  
          2. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)  

          AND
          打印第一域?yàn)閠omotoboy,第三域?yàn)锳ug的行
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '{if ($1=/tomotoboy/ && $2=/Aug/) print $0}'  
          2. awk: syntax error near line 1  
          3. awk: illegal statement near line 1  
          4. /home/l/g/tomotoboy >who | awk  '{if ($1~/tomotoboy/ && $3~/Aug/) print $0}'  
          5. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)  

          注意區(qū)分“=”與“==”,獲得兩種截然不同的結(jié)果
          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '{if ($1="tomotoboy" && $3="Aug") print $0}'  
          2. tomotoboy pts/6 Aug 20 08:27 (219.245.104.240)   
          3. tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)   
          4. tomotoboy pts/21 Aug 8 00:05 (116.29.229.116)   
          5. tomotoboy pts/35 Aug 8 00:05 (116.29.229.116)   
          6. tomotoboy pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          7. tomotoboy pts/40 Aug 7 23:46 (116.77.50.7)   
          8. tomotoboy pts/46 Aug 7 20:48 (199.40.206.191)  


          Shell代碼
          1. /home/l/g/tomotoboy >who | awk  '{if ($1=="tomotoboy" && $3=="Aug") print $0}'  
          2. tomotoboy   pts/16       Aug  7 23:33   (219.221.98.71)  


          awk內(nèi)置變量
          Shell代碼
          1. /home/l/g/tomotoboy >who|awk '{print NF,NR,$0}'  
          2. 6 1 liuzk423   pts/6        Jul 20 08:27        (219.245.104.240)   
          3. 6 2 tomotoboy   pts/16       Aug  7 23:33       (219.221.98.71)   
          4. 6 3 liuqingaihn   pts/21       Aug  8 00:05     (116.29.229.116)   
          5. 6 4 liuqingaihn   pts/35       Aug  8 00:05     (116.29.229.116)   
          6. 6 5 uyty       pts/38       Aug  7 22:09        (p3213-ipbf803souka.saitama.ocn.ne.jp)   
          7. 6 6 kenhq      pts/40       Aug  7 23:46        (116.77.50.7)   
          8. 6 7 yagamil    pts/46       Aug  7 20:48        (199.40.206.191)  


          awk內(nèi)置字符串函數(shù)
          awk內(nèi)置字符串函數(shù),awk又很多字符處理函數(shù),這里以length為例
          Shell代碼
          1. /home/l/g/tomotoboy >who| awk '{print length($1)" "$1}'  
          2. 8 liuzk423   
          3. 9 tomotoboy   
          4. 11 liuqingaihn   
          5. 11 liuqingaihn   
          6. 5 kenhq   
          7. 7 yagamil  

          如果第一域的長(zhǎng)度大于7就輸出
          Shell代碼
          1. /home/l/g/tomotoboy >who| awk '{if(length($1)>7) print length($1)" "$1}'  
          2. 8 liuzk423   
          3. 9 tomotoboy   
          4. 11 liuqingaihn   
          5. 11 liuqingaihn  


          字符串屏蔽序列
          使用字符串或正則表達(dá)式時(shí),有時(shí)需要在輸出中加入一新行或查詢一元字符。打印一新行時(shí),(新行為字符\n) ,給出其屏蔽序列,以不失其特殊含義,用法為在字符串前加入反斜線。例如使用\n強(qiáng)迫打印一新行。如果使用正則表達(dá)式,查詢花括號(hào)({ }) ,在字符前加反斜線,如/ \ { /,將在awk中失掉其特殊含義。
          Shell代碼
          1. \b 退格鍵      \t tab鍵   
          2. \f 走紙換頁    \ddd 八進(jìn)制值   
          3. \n 新行        \c 任意其他特殊字符,例如\\為反斜線符號(hào)   
          4. \r 回車鍵   
          5. /home/l/g/tomotoboy >who |awk '{print $1"\t""\t"$2"\n"}'  
          6. liuzk423                pts/6  
          7.   
          8. tomotoboy               pts/16  
          9.   
          10. liuqingaihn             pts/21  
          11.   
          12. liuqingaihn             pts/35  
          13.   
          14. kenhq                   pts/40  
          15.   
          16. yagamil                 pts/46  


          printf
          printf修飾符,prinf基本域C語言的printf相同下面開始舉例
          Shell代碼
          1. /home/l/g/tomotoboy >echo "65" |awk '{printf "%c\n",$0}'  
          2. A   
          3. /home/l/g/tomotoboy >echo "65" |awk '{printf "%d\n",$0}'  
          4. 65  
          5. /home/l/g/tomotoboy >echo "65" |awk '{printf "%c\t\t%d\n",$0,$0}'  
          6. A               65  


          awk數(shù)組
          Java代碼
          1. /home/l/g/tomotoboy >awk 'BEGIN {print split("123#456#789",myarray,"#")}'  
          2. 3  

          在上面的例子中,split返回?cái)?shù)組myarray下標(biāo)數(shù)。實(shí)際上myarray數(shù)組為:
          myarray[1]=123
          myarray[2]=456
          myarray[3]=789
          數(shù)組使用前,不必定義,也不必指定數(shù)組元素個(gè)數(shù)。經(jīng)常使用循環(huán)來訪問數(shù)組。下面是一種循環(huán)類型的基本結(jié)構(gòu):
          For (element in array) print array[element]
          對(duì)于記錄“123#456#789” ,先使用split函數(shù)劃分它,再使用循環(huán)打印各數(shù)組元素。操作腳本如下:
          Shell代碼
          1. #!/bin/awk -f   
          2. #name: arraytest.awk   
          3. #pprint out am array   
          4. BEGIN{   
          5. record="123#456#789";   
          6. split(record,myarray,"#")}   
          7. END { for (i in myarray) {print myarray[i]}}  

          要運(yùn)行腳本,使用/dev/null作為輸入文件。
          Shell代碼
          1. /home/l/g/tomotoboy >arraytest.awk /dev/null   
          2. 456  
          3. 789  
          4. 123  
          小結(jié)
          awk語言學(xué)起來可能有些復(fù)雜,但使用它來編寫一行命令或小腳本并不太難。awk是shell編程的一個(gè)重要工具。在shell命令或編程中,雖然可以使用awk強(qiáng)大的文本處理能力,但是并不要求你成為這方面的專家
          主站蜘蛛池模板: 六盘水市| 扎鲁特旗| 万州区| 石阡县| 渭南市| 彭州市| 茌平县| 桐乡市| 年辖:市辖区| 正定县| 方城县| 永善县| 哈尔滨市| 和林格尔县| 保山市| 泸水县| 上高县| 永春县| 临西县| 昌黎县| 和硕县| 台东市| 蒙自县| 兖州市| 太仆寺旗| 广南县| 莱州市| 平凉市| 建宁县| 堆龙德庆县| 通山县| 临夏市| 太原市| 玉屏| 西平县| 五家渠市| 平顶山市| 吉木乃县| 安宁市| 巴马| 新闻|