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表示第一個域,$n表示第n個域。默認域分隔符是"空白鍵"或 "[tab]鍵"
最重要的是awk還是一門編程語言,后邊詳細總結。
awk '{pattern + action}' {filenames}
盡管操作可能會很復雜,但語法總是這樣,其中 pattern 表示 AWK 在數據中查找的內容,而action 是在找到匹配內容時所執行的一系列命令。花括號({})不需要在程序中始終出現,但它們用于根據特定的模式對一系列指令進行分組。pattern就是要表示的正則表達式,用斜杠括起來。
awk語言的最基本功能是在文件或者字符串中基于指定規則瀏覽和抽取信息,awk抽取信息后,才能進行其他文本操作。完整的awk腳本通常用來格式化文本文件中的信息。
通常,awk是以文件的一行為處理單位的。awk每接收文件的一行,然后執行相應的命令,來處理文本。
有三種方式調用awk
1.命令行方式awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可選的。 input-file(s) 是待處理的文件。
在awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格。
2.shell腳本方式
將所有的awk命令插入一個文件,并使awk程序可執行,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調用。
相當于shell腳本首行的:#!/bin/sh
可以換成:#!/bin/awk
3.將所有的awk命令插入一個單獨文件,然后調用:awk -fawk-script-file input-file(s)
其中,-f選項加載awk-script-file中的awk腳本,input-file(s)跟上面的是一樣的。
last -n 5 | awk '{PRint $1}' 列出最后登錄系統的5人的名字
cat /etc/passwd | awk -F ':' '{print $1}' 列出系統上所有用戶
cat /etc/passwd | awk -F ':' '{print $1 "/t"$7}' 顯示用戶名和所對應的shell
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END{print "blue,/bin/nosh"}'
awk -F : '/root/' /etc/passwd
awk -F : '/^root/' /etc/passwd
printf使用實例,打印的好看點。printf命令的使用格式:printf format, item1, item2, ...要點:1、其與print命令的最大不同是,printf需要指定format;2、format用于指定后面的每個item的輸出格式;3、printf語句不會自動打印換行符;/nformat格式的指示符都以%開頭,后跟一個字符;如下:%c: 顯示字符的ASCII碼;%d, %i:十進制整數;%e, %E:科學計數法顯示數值;%f: 顯示浮點數;%g, %G: 以科學計數法的格式或浮點數的格式顯示數值;%s: 顯示字符串;%u: 無符號整數;%%: 顯示%自身;修飾符:N: 顯示寬度;-: 左對齊;+:顯示數值符號;例子:# awk -F: '{printf "%-15s %i/n",$1,$3}' /etc/passwd
cat /etc/passwd | awk -F ':' 'BEGIN{printf "%-15s%-15s/n", "name","shell"}{printf "%-15s%-15s/n", $1,$7} END{printf "%-15s%-15s/n","blue","/bin/nobash"} '
輸出重定向print items > output-fileprint items >> output-fileprint items | command特殊文件描述符:/dev/stdin:標準輸入/dev/sdtout: 標準輸出/dev/stderr: 錯誤輸出/dev/fd/N: 某特定文件描述符,如/dev/stdin就相當于/dev/fd/0;例子:# awk -F: '{printf "%-15s %i/n",$1,$3 > "/dev/stderr" }' /etc/passwd
1.1 awk內置變量之記錄變量:FS: field separator,讀取文件本時,所使用字段分隔符;RS: Record separator,輸入文本信息所使用的換行符;OFS: Output Filed Separator: ORS:Output Row Separator:awk -F:OFS="#"FS=":"1.2 awk內置變量之數據變量:NR: The number of input records,awk命令所處理的記錄數;如果有多個文件,這個數目會把處理的多個文件中行統一計數;NF:Number of Field,當前記錄的field個數;FNR: 與NR不同的是,FNR用于記錄正處理的行是當前這一文件中被總共處理的行數;ARGV: 數組,保存命令行本身這個字符串,如awk '{print $0}' a.txt b.txt這個命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;ARGC: awk命令的參數的個數;FILENAME: awk命令所處理的文件的名稱;ENVIRON:當前shell環境變量及其值的關聯數組;如:awk 'BEGIN{print ENVIRON["PATH"]}'
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
awk '{FS="#";print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd 注意觀察columns
1.3 用戶自定義變量gawk允許用戶自定義自己的變量以便在程序代碼中使用,變量名命名規則與大多數編程語言相同,只能使用字母、數字和下劃線,且不能以數字開頭。gawk變量名稱區分字符大小寫。
在腳本中賦值變量在gawk中給變量賦值使用賦值語句進行,例如:awk 'BEGIN{var="variable testing";print var}'在命令行中使用賦值變量gawk命令也可以在“腳本”外為變量賦值,并在腳本中進行引用。例如,上述的例子還可以改寫為:awk -v var="variable testing" 'BEGIN{print var}'
awk的操作符:1>算術操作符:-x: 負值+x: 轉換為數值;x^y: x**y: 次方x*y: 乘法x/y:除法x+y:x-y:x%y:
例:awk 'BEGIN{A=3; B=4;print A+B}'
2>賦值操作符:=+=-=*=/=%=^=**=++--需要注意的是,如果某模式為=號,此時使用/=/可能會有語法錯誤,應以/[=]/替代;例:awk 'BEGIN{A=3; B=4;print A+=4}'
3>比較操作符:x < y True if x is less than y. x <= y True if x is less than or equal to y. x > y True if x is greater than y. x >= y True if x is greater than or equal to y. x == y True if x is equal to y. x != y True if x is not equal to y. x ~ y True if the string x matches the regexp denoted by y. x !~ y True if the string x does not match the regexp denoted by y. subscript in array True if the array array has an element with the subscript subscript.
例:awk 'BEGIN{A=3; B=4;if(A>B){print "yes";print"shi"}else {print "no"}}'
awk 'BEGIN{A="root"; B="r.t";if(A~B){print "yes";print"shi"}else {print "no"}}' B變量是一個正則表達式
4>條件表達式:
例:awk 'BEGIN{A=3; B=4;if(A>B){print "yes";print"shi"}else {print "no"}}'
表達式間的邏輯關系符:&&||
例:awk 'BEGIN{A=3; B=4;if(A<B && A-1<B){print "yes";print"shi"}else {print "no"}}'
5>函數:
自定義函數和調用
awk 'function test(a,b){return a>b;} BEGIN{ if(test(4,3)){print "yes";print"shi"}else {print "no"}}'
內置函數調用
awk的內置函數split(string, array [, fieldsep [, seps ] ])功能:將string表示的字符串以fieldsep為分隔符進行分隔,并將分隔后的結果保存至array為名的數組中;數組下標為從0開始的序列;netstat -ant | awk '/:80/>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50 自己運行查看下數組元素倒敘的length([string])功能:返回string字符串中字符的個數;substr(string, start [, length])功能:取string字符串中的子串,從start開始,取length個;start從1開始計數;system(command)功能:執行系統command并將結果返回至awk命令systime()功能:取系統當前時間tolower(s)功能:將s中的所有字母轉為小寫toupper(s)功能:將s中的所有字母轉為大寫
6>循環語句:
for循環:語法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd NF是字段數量,length是內置的函數
while語法: while (condition){statement1; statment2; ...}awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwdawk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd
do-while循環:語法: do {statement1, statement2, ...} while (condition)awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
case 語句:不是所有awk都支持語法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}
break 和 continue常用于循環或case語句中
例: awk 'BEGIN{i=1;while (i<=3) {if(i==2){i++;continue};print i;i++}}'
next提前結束對本行文本的處理,并接著處理下一行;例如,下面的命令將顯示其ID號為奇數的用戶:# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
7>awk中使用數組
array[index-expression]index-expression可以使用任意字符串;需要注意的是,如果某數據組元素事先不存在,那么在引用其時,awk會自動創建此元素并初始化為空串;因此,要判斷某數據組中是否存在某元素,需要使用index in array的方式。要遍歷數組中的每一個元素,需要使用如下的特殊結構:for (var in array) { statement1, ... }其中,var用于引用數組下標,而不是元素值;
例子: awk 'BEGIN{A[0]="a";A[1]="b";A[2]="c"; for(i in A){ print i,A[i]} }'
刪除數組變量從關系數組中刪除數組索引需要使用delete命令。使用格式為:delete array[index]
例:awk 'BEGIN{A[0]="a";A[1]="b";A[2]="c"; delete A[1]; for(i in A){ print i,A[i]} }'
|
新聞熱點
疑難解答