GAWK的初印象

awk工作原理:

   第一步:執行BEGIN{action;… } 語句塊中的語句

   第二步:從文件或標準輸入(stdin) 讀取一行,然後執行pattern{action;… }語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。

   第三步:當讀至輸入流末尾時,執行END{action;…}語句塊 BEGIN 語句塊

        在awk 開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN 語句塊中

        END語句塊在awk 從輸入流中讀取完所有的行之後即被執行,比如打印所有行的分析結果這類信息彙總都是在END 語句塊中完成,它也是一個可選語句塊

        pattern 語句塊中的通用命令是最重要的部分,也是可選的。如果沒有提供pattern 語句塊,則默認執行{ print } ,即打印每一個讀取到的行,awk 讀取的每一行都會執行該語句塊



awk基本用法:

awk [options]  'program' var=value file…
awk [options]  -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file...

常用選項:
-F 指明輸入時用到的字段分隔符(不指定則默認空白)
-v var=value: (變量賦值)

  awk程序(program)通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END 語句塊,共3部分組成,program 通常 是被單引號或雙引號中

注: 普通字符串加雙引號 變量則不用加

   省略action行 ,則默認執行 print $0 的 的 操作


print格式:print item1, item2, ...

要點:

 (1) 逗號分隔符

 (2) 輸出的各item可以是字符串,也可以是數值;當前記錄的字段、變量或awk 的表達式

 (3) 如省略item ,相當於print $0  "\t" 對齊 相當於tab鍵


常用變量:

1、 FS :輸入字段分隔符,默認爲空白字符 (可以引用,-F打到的效果和這個-FS的一樣)

awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
awk –F: '{print $1,$3,$7}’ /etc/passwd

2、OFS :輸出字段分隔符,默認爲空白字符

awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd

3、RS :指定RS等於的值爲分隔符,原換行符仍有效

awk -v RS=' ' '{print }' /etc/passwd

4、ORS :輸出記錄分隔符,輸出時用指定符號代替換行符

awk -v RS=' ' -v ORS='###' '{print }' /etc/passwd

5、NF :字段數量

awk -F:  '{print NF}' /etc/fstab, 引用內置變量不用$
awk -F:   '{print $(NF-1)}' /etc/passwd

6、NR :行號(記錄數)可以把兩個鏈接起來

awk  '{print NR}' /etc/fstab 
awk  'END{print NR}' /etc/fstab

7、FNR :各文件分別計數, 行號

awk  '{print FNR}' /etc/fstab /etc/inittab

8、FILENAME :當前文件名

awk  'END{print FILENAME}' /etc/fstab

9、ARGC :命令行參數的個數

awk  '{print ARGC}' /etc/fstab /etc/inittab
awk  'BEGIN {print ARGC}' /etc/fstab /etc/inittab

10、ARGV :數組,保存的是命令行所給定的各參數

awk  'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk  'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab


格式化輸出:printf “FORMAT ”, item1, item2, ...

(1) 必須指定FORMAT

(2) 不會自動換行,需要顯式給出換行控制符,\n

(3) FORMAT 中需要分別爲後面每個item 指定格式符

格式符:與item 一一對應

     %c: 顯示字符的ASCII碼

     %d 或 %i: 顯示十進制整數

     %f:顯示爲浮點數

     %g, %G :以科學計數法或浮點形式顯示數值

     %s:顯示字符串

     %u:無符號整數

     %%: 顯示% 自身


修飾符:

  #[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度 

       eg:%3.1f三個字符寬度,小數精確一位

  -   : 左對齊(默認右對齊)  eg: %-15s 十五個字符和左邊對齊

  +   :顯示數值的正負符號 %+d


模式匹配符:~ :左邊是否和右邊匹配包含 !~ :是否不匹配

範例:
awk –F: '$0 ~ /root/{print $1}' /etc/passwd
awk '$0~“^root"' /etc/passwd
awk '$0 !~ /root/‘ /etc/passwd
awk –F: ‘$3==0’ /etc/passwd


BEGIN/END 模式

BEGIN{} :僅在開始處理文件中的文本之前執行一次

END{}  :僅在文本處理完成之後執行一次


邏輯符:

&&   與

||   或

!   非



PATTERN: 根據pattern 條件,過濾匹配的行,再做處理

(1) 如果未指定:空模式,匹配每一行

(2) /regular expression/ :僅處理能夠模式匹配到的行,需要用/ / 括起來,//之間可以寫正則

awk  '/^UUID/{print $1}'  /etc/fstab
awk  '!/^UUID/{print $1}' /etc/fstab

(3) relational expression:  關係表達式,結果爲“真”纔會被處理

    真:結果爲非0 值,非空字符串

    假:結果爲空字符串或0值

(4) 行範圍

 awk -F:  '10,20{print $1}'   /etc/passwd

eg:
 awk -F: 'i=1;j=1{print i,j}' /etc/passwd   
 awk  '!0' /etc/passwd ; awk '!1' /etc/passwd
 awk –F: '$3>=1000{print $1,$3}' /etc/passwd
 awk -F: '$3<1000{print $1,$3}' /etc/passwd
 awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
 awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd


三目運算:  selector ?if-true:if-false


if-else語句

  語法:if(condition){statement;…}[else statement]

      if(condition1){statement1}else if(condition2){statement2}else{statement3}

  使用場景:對awk取得的整行或某個字段做條件判斷

  示例:
awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
awk '{if(NF>5) print $0}' /etc/fstab
awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else{printf "root or Sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($3>=1000) printf "Common user: %s\n",$1;else printf "root or Sysuser: %s\n",$1}' /etc/passwd
df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}'
awk 'BEGIN{test=100;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'

while語句

  語法:while(condition){statement;…}

  條件“真”,進入循環;條件“假”, 退出循環

  使用場景:對一行內的多個字段逐一類似處理時使用

        對數組中的各元素逐一處理時使用

  示例:
awk  '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/grub2.cfg
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg

for語句

  語法:for(expr1;expr2;expr3) {statement;…}

awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length(i)}}'  
/etc/grub2.cfg  #統計文本中的單詞出現的次數

 特殊用法:遍歷每個元素

      for(var in array){for-body}

補充:

break   [n]  退出全部

continue     退出當前

next        控制內生循環,提前結束本行,進入下一次循環

eg:awk -F:   'if($3%2!=0  next;print  $1 )'  /etc/passwd


數組

關聯數組:array[index-expression]

 index-expression:

 (1)  可使用任意字符串;字符串要使用雙引號括起來

 (2)  如果某數組元素事先不存在,在引用時,awk 會自動創建此元素,並將其值初始化爲“空串”

     若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷

  

示例:
 weekdays[“mon”]="Monday“
 awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
 awk '!arr[$0]++' dupfile     去重
 awk '{!arr[$0]++;print $0, arr[$0]}' dupfile
 netstat -tan|awk '/^tcp\>/{statu[$NF]++}END{for (i in statu){print i,statu[i]}}'     #統計tcp的狀態出現多少次
 awk '!/^#/{print $3}' /etc/fstab |awk '{cs[$1]++}END{for(i in cs){print i,cs [i]}}'  /etc/fstab  #統計/etc/fstab文件中每個文件系統類型出現的次數
 awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for (i in count ){print i":"count [i]}}'    /etc/fstab #統計/etc/fstab文件中每個單詞出現的次數

函數

內置函數:

       rand()   返回0-1之間的隨機數,注:第一次隨機,之後的重複

       sub(r,s,[t])  以r表示的模式來查找t所表示的字符內容,並將第一次出現的內容替換爲s所表示的內容

       gsub(r,s,[t])  以r表示的模式來查找t所表示的字符內容,並將出現的全部內容替換爲s所表示的內容

       split(s,a[,r]) 以r爲分隔符,將切後的結果保存在a屬組中

實例:netstat -tan|awk '/^tcp\>/{print ($5,ip,":");count[ip[1]]++}END{for (i in count){print i,count[i]}}'    


注:函數在我們運維過程中使用較少,所以我這裏就簡單帶過,有興趣的朋友可以去看大佬們寫的博客

  http://blog.csdn.net/xiaolang85/article/details/8546744

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章