linux awk詳解
awk:
awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,
awk在其對數據分析並生成報告時,顯得尤為強大。
簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。
awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名稱得自於它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。
實際上 AWK 的確擁有自己的語言: AWK 程序設計語言 , 三位創建者已將它正式定義為“樣式掃描和處理語言”。
它允許您創建簡短的程序,這些程序讀取輸入文件、為數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其他的功能。
awk工作流程:
讀入有"\n"換行符分割的一條記錄,然後把記錄按照指定的域分隔符劃分域,填充域
$0表示所有的域,$1表示第一個域,以此類推
默認域分隔符是空白鍵或者tab鍵
-F:指定域分隔符
cat /etc/passwd | awk -F":" ‘{print $1}‘
中間可以用\t來填充
cat /etc/passwd | awk -F":" ‘{print $1"\t"$7}‘
當有BEGIN,END時AWK工作流程:
先執行begin,然後讀取文件,讀入有\n換行符分割的第一條記錄,然後安裝
指定的域分隔符劃分域,填充域,$0表示所有的域,$1表示第一個域,以此類推
隨後開始執行模式所對應的動作action
最後都執行完,最後執行end操作
cat /etc/passwd | awk -F‘:‘ ‘BEGIN {print "username bash"} {print $1","$7} END {print "run over"}‘
輸出內容需要用""包含,其中BEGIN,END都是關鍵字,必須大寫
awk內置變量:
awk中同樣定義了很多內置變量,我們可以直接像使用普通變量一樣使用他們,由於awk的版本眾多,有些內置變量並不是得到所有awk版本的支持。
說明:[A][N][P][G]表示支持該變量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
$n 當前記錄的第n個字段,比如n為1表示第一個字段,n為2表示第二個字段。 $0 這個變量包含執行過程中當前行的文本內容。 [N] ARGC 命令行參數的數目。 [G] ARGIND 命令行中當前文件的位置(從0開始算)。 [N] ARGV 包含命令行參數的數組。 [G] CONVFMT 數字轉換格式(默認值為%.6g)。 [P] ENVIRON 環境變量關聯數組。 [N] ERRNO 最後一個系統錯誤的描述。 [G] FIELDWIDTHS 字段寬度列表(用空格鍵分隔)。 [A] FILENAME 當前輸入文件的名。 [P] FNR 同NR,但相對於當前文件。 [A] FS 字段分隔符(默認是任何空格)。 [G] IGNORECASE 如果為真,則進行忽略大小寫的匹配。 [A] NF 表示字段數,在執行過程中對應於當前的字段數。 [A] NR 表示記錄數,在執行過程中對應於當前的行號。 [A] OFMT 數字的輸出格式(默認值是%.6g)。 [A] OFS 輸出字段分隔符(默認值是一個空格)。 [A] ORS 輸出記錄分隔符(默認值是一個換行符)。 [A] RS 記錄分隔符(默認是一個換行符)。 [N] RSTART 由match函數所匹配的字符串的第一個位置。 [N] RLENGTH 由match函數所匹配的字符串的長度。 [N] SUBSEP 數組下標分隔符(默認值是34)。
awk編程:
變量和賦值
print只是語句
awk ‘BEGIN {count=0} {count++;print $0} END {print "user count is ",count}‘ /etc/passwd ls -l /etc/ | grep ^- | awk ‘BEGIN{size=0} {size=size+$5} END{print size}‘
條件語句:
if(expression){ statement; statement; ...... } if(expression){ statement; statement; ...... } else { statement; } if(expression){ statement; statement; ...... } else if (expression) { statement; } else { statement; }
統計目錄下文件大小,過濾掉4096(一般都是文件夾)
ls -l | awk ‘BEGIN {size=0;} {if($5!=4096){size=size+$5}} END {print "size is:",size}‘
循環語句:
while循環
awk ‘BEGIN {count=0;while(count<5){print count;count++;}}‘
do...while循環
awk ‘BEGIN {count=0;do{print count;count++;}while(count<5)}
for循環
awk ‘BEGIN {for(count=0; count<5; count++){print count}}‘
使用數組求和,for...in循環
awk ‘{sum[$1]+=$2}END{for(k in sum){print k" "sum[k]}}‘
awk內置函數:
算術:
atan2(y,x) 返回 y/x 的反正切。 cos(x) 返回 x 的余弦;x 是弧度。 sin(x) 返回 x 的正弦;x 是弧度。 exp(x) 返回 x 冪函數。 log(x) 返回 x 的自然對數。 sqrt(x) 返回 x 平方根。 int(x) 返回 x 的截斷至整數的值。 rand() 返回任意數字 n,其中 0 <= n < 1。 srand([expr]) 將 rand 函數的種子值設置為 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。
字符串:
gsub(reg,str1,str2) 使用str1替換所有str2中符合正則表達式reg的子串 sub(reg,str1,str2) 含義與gsub相同,只不過gsub是替換所有匹配,sub只替換第一個匹配 index(str,substr) 返回substr在str中第一次出現的索引,註意索引從1開始計算,如果沒有則返回0 length(str) 返回str字符串的長度,length函數還可以返回數組元素的個數 blength(str) 返回字符串的字節數 match(str,reg) 與index函數一樣,只不過reg使用正則表達式,例如match("hello",/lo/) split(str,array,reg)將str分隔成數組保存到array中,分隔使用正則reg,或者字符串都可以,返回數組長度 tolower(str) 轉換為小寫 toupper(str) 轉換為大寫 substr(str,start,length) 截取字符串,從start索引開始的length個字符,如不指定length則截取到末尾,索引從1開始
其他:
system(command) 執行系統命令,返回退出碼 mktime( YYYY MM dd HH MM ss[ DST]) 生成時間格式 strftime(format,timestamp) 格式化時間輸出,將時間戳轉換為時間字符串 systime() 得到時間戳,返回從1970年1月1日開始到當前時間(不計閏年)的整秒數
參考:https://www.cnblogs.com/wangqiguo/p/5863266.html
linux awk詳解