awk:
文本處理三劍客:grep系,sed,awk
grep系:grep,egrep,fgrep,基於PATTERN進行文本過濾;
sed:流編輯器,逐行編輯器;模式空間,保持空間;
awk:報告生成器;格式化文檔輸出;web
gawk命令: gawk - pattern scanning and processing language 格式: gawk [ options ] 'program' file ... program:[/PATTERN/]{ACTION statement; ...} PATTERN部分:決定動做語句什麼時候觸發以及經過什麼事件來觸發; BEGIN, END ACTION statement:對數據進行特定的處理,一般放置在{}中; print, printf 基本概念: 分隔符: 輸入分隔符: awk對數據進行處理時,會根據特定的標識符號對數據進行分段處理,這種標識符號就稱爲"輸入分隔符",默認的輸入分隔符是空白字符;若是指定的分隔符並無被數據包括,則只有換行分隔符有效; 輸出分隔符: awk對數據處理完成後,會以特定的標識符號對各個字段進行鏈接後輸出,這種標識符號就稱爲"輸出分隔符",默認的輸出分隔符是空白字符; 記錄:由換行符進行分隔的數據中一行,就稱爲一條記錄(Record);一般在使用awk處理數據時,使用內置變量$0來保存整個記錄的內容; 字段:通過分隔符分隔以後的每個數據分段,都成爲一個字段(Field);一般在使用awk處理數據時,使用$1,$2...$NF等內置變量來存儲各個字段的數據; awk的工做原理: 1.首先,執行BEGIN{ACTION statement;...}語句塊中的語句; 2.其次,從文件中或着標準輸入讀取一行,根據PATTERN的匹配結果執行後面的ACTION語句塊中的內容;而後逐行重複該過程已完成數據處理,直到數據所有被讀取完畢; 3.最後,在全部的語句塊都執行完成以後,退出awk進程以前,執行END{ACTION statement;...}語句塊中的語句; 注意: 1) BEGIN語句塊在awk開始處理數據內容以前就被執行;一般用於生成表頭;此語句塊是可選語句塊; 2) END語句塊在處理完全部的數據以後,纔會被執行;一般用於數據彙總;此語句塊是可選語句塊; 3) PATTERN語句塊中的通用命令是最重要的部分,所以PATTERN語句塊不能省略,但其中的ACTION能夠省略,若是省略,則默認執行print動做,即:顯示數據的各行; 4) awk在執行PATTERN語句塊時,默認循環遍歷數據中的各個記錄; 經常使用選項: -f,--file program-file:從指定的文件中加載program語句塊,而不是經過命令行給出相關的程序內容; -F,--field-separator fs:指定字段的輸入分隔符;默認是空白字符; -v,--assign var=val:用於聲明自定義變量併爲變量賦值; awk的經常使用用法: 1.變量: 內建變量: FS:input field separator,輸入字段分隔符,默認爲空白字符; OFS:output field separator,輸出字段分隔符,默認爲空白字符; 示例: ~]# awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd RS:The input record separator,輸入記錄(行)分隔符,默認爲換行符; 注意:即便指定了額外的輸入記錄分隔符,原有的換行符依然有效; ORS:The output record separator,輸出記錄分隔符,默認爲換行符; 示例: ~]# awk -v RS=':' -v ORS='#' '{print $0}' /etc/passwd NF:The number of fields,每一行中的字段的總數; 示例: ~]# awk -F: '{print NF}' /etc/passwd 顯示指定文件中每行中的字段的數量; ~]# awk -F: '{print $NF}' /etc/passwd 顯示指定文件中每行中最後一個字段的內容; ~]# awk -F: '{print $(NF-1)}' /etc/passwd 顯示指定文件中每行中倒數第二個字段的內容; NR:The total number of input records,行的總數;若是僅處理一個文件,能夠將NR的值看成此文件中各行的行號; 示例: ~]# awk '{print NR}' /etc/fstab FNR:The input record number in the current input file,對於不一樣的文件分別統計其行的數量;即便處理多個文件,也能夠顯示每一個文件中每行的行號; 示例: ~]# awk '{print FNR}' /etc/fstab /etc/issue FILENAME:The name of the current input file,當前正在被處理的文件的文件名; 示例: ~]# awk 'END{print FILENAME}' /etc/fstab ARGC:The number of command line arguments,命令行中參數的數量;包括awk命令自己,但不包括awk命令的選項部分和program部分; 示例: ~]# awk 'END{print ARGC}' /etc/fstab /etc/issue /etc/passwd ARGV:Array of command line arguments,由命令行中全部的參數構成的數組; 示例: ~]# awk 'END{print ARGV[1]}' /etc/fstab /etc/issue /etc/passwd 顯示命令行中的第N個參數; 自定義變量: 定義方式: -v var_name=value 注意:變量名字母大小寫敏感的; 示例: ~]# awk -v var='hello' -F: '{print $1"," var}' /etc/passwd 經常使用的ACTION: 2.print:Print the current record,以標準格式輸出結果; 格式: print item1,item2,... 注意: 1) 各item之間須要使用","進行分隔; 2) 輸出的各item能夠是字符串,能夠是數字,能夠是當前記錄中的字段,能夠是變量,能夠是awk的表達式; 3) 若是省略了item,則默認的item爲$0,即:輸出整行; 示例: ~]# awk '{print}' /etc/issue ~]# awk '{print $1,$3,$NF}' /etc/issue 3.printf:Format and print,以特定的格式輸出結果; 格式: printf "FORMAT" item1,item2,... 注意: 1) 必須給出合適的輸出格式; 2) 默認不會自動換行,若是想要在輸出結果中換行顯示,須要顯式給出換行控制符號,即:\n; 3) FORMAT中須要爲後面的每個item單獨指定一個格式化符號; 經常使用的FORMAT: %c:以ASCII碼錶中的內容顯示字符信息; %d, %i:顯示十進制整數; %e, %E:以科學計數法來顯示數字;浮點類型; %f, %F:顯示十進制數字的浮點形式; %g, %G:以科學計數法顯示浮點數字; %u:顯示無符號十進制數; %s:顯示字符串; %x, %X:顯示無符號的十六進制整數; %%:顯示%; 修飾符: #[.#]:第一個數字用來控制顯示寬度;第二個數字表示小數點的精度; 如:%5s, $8.3f -:表示採用左對齊方式顯示;默認是右對齊; +:顯示數字的正負符號; 示例: ~]# awk -F: '{printf "%20s:%-+5d\n",$1,$3}' /etc/passwd 4.操做符: 算術運算操做符: 雙目運算符: x+y, x-y, x*y, x/y, x^y, x%y 單目運算符: -x:將正整數轉換爲負整數; +x:將字符串轉換爲數值; 示例: ~]# awk -F : 'END{print 100^2}' /etc/passwd 字符串操做符: 無任何操做符號時,即爲字符串鏈接操做; 賦值操做符: =, +=, -=, *=, /=, ^=, %= ++, -- 比較操做符: ==, !=, >, >=, <, <= 示例: ~]# awk -F : '$3==1000{print $0}' /etc/passwd 模式匹配操做符: ~:操做符左側的字符串是否可以被右側的PATTERN所匹配; !~:操做符左側的字符串是否不能被右側的PATTERN所匹配; 示例: ~]# awk -F : '$NF~/bash/{print $0}' /etc/passwd 邏輯運算操做符: && || ! 示例: ~]# awk -F: '$3>=1000&&$3<=1100{print $0}' /etc/passwd 條件表達式: selector(condition)?if-true-expression:if-false-expression 示例: ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="SuperUser or Sysuser";printf "%20s: %-20s\n",$1,usertype}' /etc/passwd 5.PATTERN部分: 1) empty:空模式,不加區分地處理文件的每一行; 2) [!]/REGEXP/:僅處理[不]能被PATTERN匹配到的行; 示例: ~]# awk -F: '/^r/{print $0}' /etc/passwd ~]# awk -F: '!/n$/{print $0}' /etc/passwd 3) 關係表達式: $3>=1000 $NF~/bash/ 4) 行域,行範圍: 關係表達式的邏輯運算:FNR>=10&&FNR<==20 示例: ~]# awk 'NR>=15&&NR<=20{print NR,$0}' /etc/passwd /REGEXP1/,/REGEXP2/: 從被REGEXP1匹配的行開始,直到被REGEXP2匹配的行結束,這期間的全部行;凡是屬於此類的匹配結果,有多少組就顯示多少組; 示例: ~]# awk -F: '/^r/,/^a/{print NR,$0}' /etc/passwd 5) BEGIN/END模式: BEGIN{} 僅在開始處理文件中的第一行文本數據以前執行一次的語句塊;多用於輸出特定格式的表頭信息; 示例: ~]# awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}' /etc/passwd END{} 僅在文本處理完成但awk命令還沒有退出時執行一次的語句塊;多用於數據信息的彙總; 示例: ~]# awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}END{print "------------------------------------------------------------------\n",NR " users"}' /etc/passwd 注意: 1) BEGIN語句塊,PATTERN語句塊和END語句塊的順序,一般來說是: BEGIN{}PATTERN{}END{} 2) BEGIN語句塊和END語句塊是可選的,但PATTERN語句塊必需要給出; 6.經常使用的ACTIONS 1) 表達式(Expression) 2) 組合語句(Compound Statements) 3) 輸入語句(Input Statements) 4) 輸出語句(Output Statements) 5) 控制語句(Control Statements) 7.控制語句: if (condition) statement [ else statement ] while (condition) statement do statement while (condition) for (expr1; expr2; expr3) statement for (var in array) statement break continue exit [ expression ] switch (expression) { case value|regex : statement ... [ default: statement ] } next 1) if ... else: 語法: if (condition) statement [ else statement ] 使用場景:對awk取得的整行或某個字段作條件判斷; 示例: ~]# awk -F: '{if($3>=1000){print "CommonUser:",$1}else{print "Sysuser:",$1}}' /etc/passwd ~]# awk '/^[^#]/{if(NF==6){print}}' /etc/fstab 分析磁盤上各個文件系統的空間利用率: ~]# df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=80){print $1}}' 2) while循環: 語法: while (condition) statement 使用場景: a.對一行內的多個字段逐一作相同或相似的操做處理時使用; b.對數組中的各數組元素作遍歷處理時使用; while循環的特色:條件爲真,進入循環;一旦條件爲假,則退出循環; 示例: ~]# awk '{i=1;while(i<=NF){print $i,length($i);i++}}' testfile 3) do ... while語句: 語法: do statement while (condition) 意義:與while循環相同,但statement語句段至少被執行一次; 4) for循環: 語法: for (expr1; expr2; expr3) statement expr1:variable assignment,變量賦初值; expr2:circle condition,循環條件判斷; expr3:interation process,變量值修正方法; 示例: ~]# awk '{for(i=1;i<=NF;i++){print $i,length($i)}}' testfile for (var in array) statement 5) switch ... case語句 語法: switch (expression) { case value|regex:statement;case value2|regex2:statement;... [ default: statement ] } 使用場景: 用於進行字符串比較判斷; 6) break和continue語句: break [n] continue 注意:其使用場景是行內多個字段間作循環時的循環控制方式; 示例: ~]# awk '{for(i=1;i<=NF;i++){if(length($i)<5){continue}else{print $i,length($i)}}}' testfile 7) next語句: 在awk處理數據時,提早結束對當前行的處理,而直接開始處理下一行; 示例: ~]# awk -F: '{if($3%2==1){next}else{print $1,$3}}' /etc/passwd ~]# awk -F: '{if($3%2==1)next;print $1,$3}' /etc/passwd 8.數組——Array 用戶自定義的數組,通常使用關聯數組:array_name[index_expression] 注意: 1) index_expression可使用任意的字符串,但字符串必須放在雙引號中; 2) 支持弱變量數組,即:若是某數組元素事先不存在,當引用該元素時,awk會自動建立此元素,併爲此元素賦"空字符串"做爲其初始值; 示例: ~]# awk 'BEGIN{name["leader"]="zhangsan";name["mem1"]="lisi";name["mem2"]="bob";print "Leader:",name["leader"],"Member:",name["mem1"],name["mem2"]}' ~]# awk 'BEGIN{name["leader"]="zhangsan";name["mem1"]="lisi";name["mem2"]="bob";for(i in name){print name[i]}}' 查看當前系統上全部服務的不一樣TCP狀態的鏈接數量的統計: ~]# netstat -nalt | awk '/^tcp\>/{state[$NF]++}END{for(stat in state){printf "%15s: %-10d\n",stat,state[stat]}}' 用於統計本服務器web站點的每一個用戶的請求數值: ~]# awk '{ipaddr[$1]++}END{for(ip in ipaddr){print ip,ipaddr[ip]}}' /var/log/httpd/access_log 用於統計本服務器web站點的UV值: ~]# awk '{ipaddr[$1]++}END{for(ip in ipaddr){print ip,ipaddr[ip]}}' /var/log/httpd/access_log | wc -l 9.函數: 內建函數: 數值函數:Numeric Functions rand():返回一個介於0到1之間的隨機數; sqrt():對於指定的數值進行開二次方; 字符串函數:String Functions length():計算給定字符串的長度; gsub(r, s [, t]):以r表示的模式來查找t表示的字符串中可以被匹配的內容,並將全部出現的內容替換成s表示的內容; split(s, a [, r [, seps] ]):以seps做爲分隔符,利用r表示的模式進行匹配,將s表明的字符串分割以後,保存在a表示的數組中; 自定義函數: function name(parameter list) { statements }