1. 程式人生 > >Shell程式設計四劍客之AWK

Shell程式設計四劍客之AWK

AWK是一個優良的文字處理工具,LinuxUnix環境中現有的功能最強大的資料處理引擎之一,以Aho、Weinberger、Kernighan三位發明者名字首字母命名為AWK,AWK是一個行級文字高效處理工具,AWK經過改進生成的新的版本有Nawk、Gawk,一般Linux預設為Gawk,Gawk是 AWK的GNU開源免費版本。

AWK基本原理是逐行處理檔案中的資料,查詢與命令列中所給定內容相匹配的模式,如果發現匹配內容,則進行下一個程式設計步驟,如果找不到匹配內容,則繼續處理下一行。其語法引數格式為,AWK常用引數、變數、函式詳解如下:

awk    'pattern   +   {action}'     file

  1. AWK基本語法引數詳解:
  1. 單引號' '是為了和shell命令區分開;
  2. 大括號{ }表示一個命令分組;
  3. pattern是一個過濾器,表示匹配pattern條件的行才進行Action處理;
  4. action是處理動作,常見動作為Print;
  5. 使用#作為註釋,pattern和action可以只有其一,但不能兩者都沒有。
  1. AWK內建變數詳解:
  1. FS 分隔符,預設是空格;
  2. OFS 輸出分隔符;
  3. NR 當前行數,從1開始;
  4. NF 當前記錄欄位個數;
  5. $0 當前記錄;
  6. $1~$n 當前記錄第n個欄位(列)。
  1. AWK內建函式詳解:
  1. gsub(r,s):在$0中用s代替r;
  2. index(s,t):返回s中t的第一個位置;
  3. length(s):s的長度;
  4. match(s,r):s是否匹配r;
  5. split(s,a,fs):在fs上將s分成序列a;
  6. substr(s,p):返回s從p開始的子串。
  1. AWK常用操作符,運算子及判斷符:
  1. ++ --                           增加與減少( 前置或後置);
  2. ^ **                            指數( 右結合性);
  3. ! + -                            非、一元(unary) 加號、一元減號;
  4. + - * / %                      加、減、乘、除、餘數;
  5. < <= == != > >=                       數字比較;
  6. &&                            邏輯and;
  7. ||                                 邏輯or;
  8. = += -= *= /= %= ^= **=           賦值。
  1. AWK與流程控制語句:
  1. if(condition) { } else { };
  2. while { };
  3. do{ }while(condition);
  4. for(init;condition;step){ };
  5. break/continue。

常用AWK工具企業演練案列:

  1. AWK列印硬碟裝置名稱,預設以空格為分割:

df    -h|awk  '{print  $1}'

  1. AWK以空格、冒號、\t、分號為分割:

awk  -F '[ :\t;]'  '{print  $1}'            jfedu.txt

  1. AWK以冒號分割,列印第一列,同時將內容追加到/tmp/awk.log下:

awk  -F:  '{print $1 >>"/tmp/awk.log"}'  jfedu.txt

  1. 列印jfedu.txt檔案中的第3行至第5行,NR表示列印行,$0表示文字所有域:

awk 'NR==3,NR==5  {print}'             jfedu.txt

awk 'NR==3,NR==5  {print $0}'          jfedu.txt

  1. 列印jfedu.txt檔案中的第3行至第5行的第一列與最後一列:

awk 'NR==3,NR==5 {print $1,$NF}'       jfedu.txt

  1. 列印jfedu.txt檔案中,長度大於80的行號:

awk   'length($0)>80 {print NR}'        jfedu.txt

  1. AWK引用Shell變數,使用-v或者雙引號+單引號即可:

awk -v STR=hello  '{print STR,$NF}'      jfedu.txt

STR="hello";echo| awk  '{print "'${STR}'";}'

  1. AWK以冒號切割,列印第一列同時只顯示前5行:

cat  /etc/passwd|head -5|awk  -F:   '{print $1}'

awk  -F:  'NR>=1&&NR<=5  {print $1}'  /etc/passwd

  1. Awk指定檔案jfedu.txt第一列的總和:

cat jfedu.txt |awk '{sum+=$1}END{print sum}'

  1. AWK NR行號除以2餘數為0則跳過該行,繼續執行下一行,列印在螢幕:

awk  -F:  'NR%2==0 {next} {print NR,$1}'  /etc/passwd

  1. AWK新增自定義字元:

ifconfig  eth0|grep "Bcast"|awk '{print "ip_"$2}'

  1. AWK格式化輸出passwd內容,printf列印字串,%格式化輸出分隔符,s表示字串型別,-12表示12個字元,-6表示6個字元:

awk -F:  '{printf "%-12s %-6s %-8s\n",$1,$2,$NF}'  /etc/passwd

  1. AWK OFS輸出格式化\t:

netstat -an|awk '$6 ~ /LISTEN/&&NR>=1&&NR<=10 {print NR,$4,$5,$6}' OFS="\t" 

  1. AWK與if組合實戰,判斷數字比較:

echo 3 2 1 | awk '{ if(($1>$2)||($1>$3)) { print $2} else {print $1} }'

  1. AWK與陣列組合實戰,統計passwd檔案使用者數:

awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}'  /etc/passwd

  1. awk分析Nginx訪問日誌的狀態碼404、502等錯誤資訊頁面,統計次數大於20的IP地址。

awk '{if ($9~/502|499|500|503|404/) print $1,$9}' access.log|sort|uniq –c|sort –nr | awk '{if($1>20) print $2}'

  1. 用/etc/shadow檔案中的密文部分替換/etc/passwd中的"x"位置,生成新的/tmp/passwd檔案。

awk 'BEGIN{OFS=FS=":"} NR==FNR{a[$1]=$2}NR>FNR{$2=a[$1];print >>"/tmp/passwd"}' /etc/shadow /etc/passwd

  1. Awk統計伺服器狀態連線數:

netstat -an | awk '/tcp/ {s[$NF]++} END {for(a in s) {print a,s[a]}}'

netstat -an | awk '/tcp/ {print $NF}' | sort | uniq -c