Shell編程之---awk命令詳解

來源:互聯網
上載者:User

標籤:shell   awk   Regex   

awk編程
   awk是一種程式設計語言。gawk、是最新版本,當前的linux版本用的都是gawk
   awk是gawk的軟連結

awk工作原理

    BEGIN   #在未讀取檔案行之前執行
    主輸入迴圈 (main input loop),反覆執行,直到終止條件觸發
    END     #在讀取檔案行完畢後執行


awk的三種調用方法
1、在shell命令列輸入命令調用awk
   #awk [-f 域分隔字元] ‘awk cmd‘ file

2、在awk程式段插入指令檔,然後通過awk命令調用他
   #awk -f ‘awk.sh‘ file

3、直接調用awk指令碼
   #./awk file
=====================================================
awk模式比對
任何awk語句都由模式(pattern)和動作(action)組成
    模式是一組用於測試輸入行是否需要執行動作的規則(模式決定動作何時觸發和觸發事件)
    動作是包含語句、函數和運算式的執行過程  (執行對輸入行的處理)

在test檔案中一旦有空行,則列印出來"This is a empty line!!!"
   #awk ‘/^$/{print "This is a empty line!!!"}‘ test
=====================================================
記錄和域  

awk將每個輸入檔案行定義為記錄,行中的每個字串定義為域,分隔域的符號叫做域分隔字元

vim student

Li Hao njue 025-83481010
Zhang Ju nju 025-83466534
Wang Bin seu 025-83494883
Zhu Lin njupt 025-83680010


按順序列印出student檔案中的2、1、4、3域
   #awk ‘{print $2,$1,$4,$3}‘ student

列印出student中所有的域
   #awk ‘{print $0}‘ student

根據運算運算式列出第三個域的值
   #awk ‘BEGIN {one=1;two=2}{print $(one+two)}‘ student

以tab鍵位分隔字元列印出student檔案中第三個域
   #awk ‘BEGIN {FS="\t"} {print $3}‘ student

Li Hao,njue,025-83481010
Zhang Ju,nju,025-83466534
Wang Bin,seu,025-83494883
Zhu Lin,njupt,025-83680010

以逗號為域分隔字元列印出所有的域的內容
   #awk ‘BEGIN {FS=","} {print $0}‘ student

以逗號為域分隔字元列印出1、3域的內容
   #awk ‘BEGIN {FS=","} {print $1,$3}‘ student

abc d   #中間兩個tab
abc d          #中間一個tab

列印出第一個域和d(兩種方式)
   #awk ‘BEGIN {FS="\t\t"} {print $1,$2}‘ xx
   #awk ‘BEGIN {FS="\t"} {print $1,$3}‘ xx

列印出第一個域和上面的d
   #awk ‘BEGIN {FS="\t"} {print $1,$2}‘ xx

===============================================================
關係運算子
< #小於
> #大於
<= #小於等於
>= #大於等於
== #等於
!= #不等於
~ #匹配Regex
!~ #不匹配Regex

在/etc/passwd檔案中列印出第一個域匹配於root的內容
   #awk ‘BEGIN {FS=":"} $1~/root/‘ /etc/passwd 

在/etc/passwd檔案中列印出全部域匹配於root的內容
   #awk ‘BEGIN {FS=":"} $0~/root/‘ /etc/passwd
  
在/etc/passwd檔案中列印出全部域中不匹配nologin的內容
   #awk ‘BEGIN {FS=":"} $0!~/nologin/‘ /etc/passwd

在/etc/passwd檔案中判斷,如果UID小於GID,那麼輸出所有匹配的值
   #awk ‘BEGIN {FS=":"} {if($3<$4) print $0}‘ /etc/passwd

在/etc/passwd檔案中判斷,如果UID大於等於GID,那麼輸出所有匹配的值
   #awk ‘BEGIN {FS=":"} {if($3>=$4) print $0}‘ /etc/passwd

===============================================================
布林運算子
|| #邏輯或
&& #邏輯與
! #邏輯非

列印出/etc/passwd檔案中UID等於10或者GID等於10的行
   #awk ‘BEGIN {FS=":"} {if($3==10||$4==10) print $0}‘ /etc/passwd

列印出/etc/passwd檔案中UID等於GID,並且登入shell都相同的匹配資訊
   #awk ‘BEGIN {FS=":"} {OFS=":"} {if($3==$4&&$7="/sbin/nologin") print $0}‘ /etc/passwd

列印出/etc/passwd檔案中UID匹配於10或GID匹配於10的匹配資訊
   #awk ‘BEGIN {FS=":"} {if($3~10||$4~10) print $0}‘ /etc/passwd
  
================================================================
運算式 awk運算式用於儲存、操作和擷取資料,一個awk運算式可由數值,字元常量,變數,操作符,函數和正則組成
+ #加
- #減
* #乘
/ #除
% #模
^或** #乘方
++x #在返回x值之前,x變數加1
x++ #在返回x值之後,x變數加1

使用x+=1來列出檔案test中的空行的行數
   #awk ‘/^$/ {print x+=1}‘ test
 
第1行為0,然後遞迴+1列出test檔案中的空行行數
   #awk ‘/^$/{print x++}‘ test

第1行為1,然後遞迴+1列出test檔案中的空行行數
   #awk ‘/^$/{print ++x}‘ test

執行個體
Li    hao,njue,025-83481010,85,92,78,94,88
Zhang  Ju,nju ,025-83466534,89,90,75,90,86
Wang  Bin, seu,025-83494883,84,88,80,92,84
Zhu  Lin,njupt,025-83680010,98,78,81,87,76

求出檔案student檔案中學生的平均值
   #awk ‘BEGIN {FS=","} {total=$4+$5+$6+$7+$8} {avg=total/5} {print $1,avg}‘ student

================================================================
系統變數:awk定義了很多內建變數用於設定環境變數資訊,我們稱它為系統變數,這些系統變數分為兩種
       1、用於改變awk的預設值,如域分隔字元
       2、用於定義系統值,在處理檔案時可以讀取這些系統值,如記錄中域數量,目前記錄數,當前檔案名稱,awk動態改變第二種系統變數的值

awk環境變數及其意義
#n #目前記錄的第n個域,域間由FS分割
#0 #記錄的所有域
ARGC #命令列參數的數量
ARGIND #命令列中當前檔案的位置(以0開始標號)
ARGV #命令列參數的數組
CONVFMT #數字轉換格式
ENVIRON #環境變數關聯陣列
ERRNO #最後一個系統錯誤的描述
FILEDWIDTHS #欄位寬度列表,以空格鍵分隔
FILENAME #當前檔案名稱
FNR #瀏覽檔案的記錄數
FS #欄位分隔符號,預設是空格鍵
IGONRECASE #布爾變數,如果為真,則進行忽略大小寫匹配
NF #目前記錄中的域數量
NR #目前記錄數
OFMT #數位輸出格式
OFS #輸出域分隔字元,預設是空格鍵
ORS #輸出記錄分隔字元,預設是分行符號
RLENGTH #由match函數所匹配的字串長度
RS #記錄分隔字元,預設是空格鍵
RSTART #由match函數所匹配的字串的第1個位置
SUBSEP #數組下標分隔字元,預設值是\034

輸出檔案student,並在最前面加入 目前記錄數,目前記錄中域數量,在檔案底部輸出檔案名

   #awk ‘BEGIN {FS=","} {print NR,NF,$0} END {print FILENAME}‘ student

====================================================================
格式化輸出 awk借鑒了C語言的文法,定義了printf輸出語句,規定輸出的格式
    printf (格式控制符,參數)

printf語句包含兩部分
    1、格式控制符,都是以%符號開始,用以描述格式規範
    2、參數列表,比如變數名列表,與格式控制符相對應,是輸出的對象、


printf修飾符及其意義
- #靠左對齊
width #域的步長
.prec #小數點右邊的位元

printf格式符及其意義
%c #ASCII字元
%d #整型數
%e #浮點數,科學記號標記法
%f #浮點數
%o #八進位
%s #字串
%x #十六進位數

在student中列印出字串$2和整型數$8,並且$2之後tab,$8之後換行
   #awk ‘BEGIN {FS=","} {printf("%s\t%d\n",$2,$8)}‘ student

將數字65轉換為ASCII碼
   #awk ‘BEGIN {printf("%c\n",65)}‘

將2014轉換為浮點數,預設小數位六位
   #awk ‘BEGIN {printf("%f\n",2014)}‘

列印出student檔案中的第一個域和第三個域,並且第一個域的字串和第三個域的字串相差15個空格   
   #awk ‘BEGIN {FS=","} {printf("%-15s\t%s\n",$1,$3)}‘ student

列印出student檔案中的第一個域和第三個域,並且在行首加入第一個域的注釋Name,第三個域的注釋Phonenumber
   #awk ‘BEGIN {FS=",";print "Name\t\tPhonenumber"} {printf("%-16s%s\n",$1,$3)}‘ student 

列印出浮點數控制在10為,小數點後保留三位的數
   #awk ‘BEGIN {printf("%10.3f\n",20141126)}‘  #如果數不滿10位,則會按空格補齊
2011111.000 滿10位  
   201.000      不滿10位


===================================================================
內建字串函數 awk提供了強大的內建字串函數,用於實現文本的字串替換、尋找以及分隔等功能

awk字串函數及其意義
gsub(r,s) #在輸入檔案中用s替換r
gsub(r,s,t) #在t中用s替換r
index(s,t) #返回s中字串第一個t的位置
length(s) #返回s的長度
match(s,t) #測試s是否包含匹配t的字串
split(r,s,t) #在t上將r分成序列s
sub(r,t,s) #將t中第1次出現的r替換為s
substr(r,s)         #返回字串r中從s開始的尾碼部分
substr(r,s,t) #返回字串r中從s開始長度為t的尾碼部分

在passwd中把第一個域的root替換為"My name is root",並輸出為:格式列印出來
   #awk ‘BEGIN {FS=":";OFS=":"} gsub(/root/,"my name is root",$1) {print $0}‘ /etc/passwd 

在passwd中把所有域的root替換為"My name is root",並輸出為:格式列印出來
   #awk ‘BEGIN {FS=":";OFS=":"} gsub(/root/,"My name is root") {print $0}‘ /etc/passwd

列印出abcdefg字串中f出現的首位置
   #awk ‘BEGIN {print index("abcdefg","f")}‘

列印出"This is a httpd server script"這串字串的長度
   #awk ‘BEGIN {print length("This is a httpd server script")}‘

測試"This is a httpd server script!!!"這串字串中!的首位置
   #awk ‘BEGIN {print match("This is a httpd server sctipt!!!","!")}‘

測試"This is a httpd server sctipt!!!"這串字串中C的首位置(忽略大小寫)
   #awk ‘BEGIN {IGNORECASE=1;print match("This is a httpd server sctipt!!!",/C/)}‘

將字串"This script is a httpd server script!!!"中第一個出現的sctipt替換為SCRIPT
   #awk ‘BEGIN {file="This script is a httpd server script!!!";sub(/script/,"SCRIPT",file);printf("%s\n",file)}‘

將student文本中第一個域匹配Li行中的第一個出現的10替換為99
   #awk ‘BEGIN {FS=","} {$1~Li sub(/10/,"99",$0);print $0}‘ student

返回file檔案中從第5個字元開始的尾碼部分 file="This script is a httpd server script!!!"
   #awk ‘BEGIN {file="This script is a httpd server script!!!";print substr(file,6)}‘

返回file檔案中從第6個字元開始長度為9的尾碼部分
   #awk ‘BEGIN {file="This script is a httpd server script!!!";print substr(file,6,9)}‘

在student檔案記錄首部插入記錄行號和域數,並且使用分隔字元.進行分隔列印
   #awk ‘BEGIN {FS=","} {print NR,NF,$0}‘ OFS="." student            
   



Shell編程之---awk命令詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.