簡單使用:
awk :對於檔案中一行行的獨處來執行操作 。
awk -F :'{print $1,$4}' :使用‘:’來分割這一行,把這一行的第一第四個域列印出來 。
詳細介紹:
AWK命令介紹
awk語言的最準系統是在檔案或字串中基於指定規則瀏覽和抽取資訊,awk抽取資訊後,才能進行其他文本操作,完整的awk指令碼通常用來格式化文字檔中的資訊
1. 調用awk:
第一種命令列方式,如:
awk [-Field-separator] 'commands' input-file(s)
這裡commands是真正的awk命令,[-F域分隔字元]是可選的,awk預設使用空格分隔,因此如果要瀏覽域間有空格的文本,不必指定這個選項,但如果瀏覽如passwd檔案,此檔案各域使用冒號作為分隔字元,則必須使用-F選項: awk -F : 'commands' input-file
第二種,將所有awk命令插入一個檔案,並使awk程式可執行,然後用awk命令直譯器作為指令碼的首行,以便通過鍵入指令碼名稱來調用它
第三種,將所有awk命令插入一個單獨檔案,然後調用,如:
awk -f awk-script-file input-file
-f選項指明在檔案awk-script-file的awk指令碼,input-file是使用awk進行瀏覽的檔案名稱
2. awk指令碼:
awk指令碼由各種操作和模式組成,根據分隔字元(-F選項),預設為空白格,讀取的內容依次放置到對應的域中,一行一行記錄讀取,直到檔案尾
2.1. 模式和動作
任何awk語句都是由模式和動作組成,在一個awk指令碼中可能有許多語句。模式部分決定動作語句何時觸發及觸發事件。動作即對資料進行的操作,如果省去模式部分,動作將時刻保持執行狀態
模式可以是任何條件陳述式或複合陳述式或Regex,模式包含兩個特殊欄位BEGIN和END,使用BEGIN語句設定計數和列印頭,BEGIN語句使用在任何文本瀏覽動作之前,之後文本瀏覽動作依據輸入檔案開始執行;END語句用來在awk完成文本瀏覽動作後列印輸出文本總數和結尾狀態標誌,有動作必須使用{}括起來
實際動作在大括弧{}內指明,常用來做列印動作,但是還有更長的代碼如if和迴圈looping語句及迴圈退出等,如果不指明採取什麼動作,awk預設列印出所有瀏覽出的記錄
2.2. 域和記錄:
awk執行時,其瀏覽標記為$1,$2...$n,這種方法稱為域標記。使用$1,$3表示參照第1和第3域,注意這裡使用逗號分隔域,使用$0表示使用所有域。例如:
awk '{print $0}' temp.txt > sav.txt
表示列印所有域並把結果重新導向到sav.txt中
awk '{print $0}' temp.txt|tee sav.txt
和上例相似,不同的是將在螢幕上顯示出來
awk '{print $1,$4}' temp.txt
只列印出第1和第4域
awk 'BEGIN {print "NAME GRADE\n----"} {print $1"\t"$4}' temp.txt
表示打資訊頭,即輸入的內容的第一行前加上"NAME GRADE\n-------------",同時內容以tab分開
awk 'BEGIN {print "being"} {print $1} END {print "end"}' temp
同時列印資訊頭和資訊尾
2.3. 條件操作符:
<、<=、==、!=、>=、~匹配Regex、!~不匹配Regex
匹配:awk '{if ($4~/ASIMA/) print $0}' temp 表示如果第四個域包含ASIMA,就列印整條
精確匹配:awk '$3=="48" {print $0}' temp 只列印第3域等於"48"的記錄
不匹配: awk '$0 !~ /ASIMA/' temp 列印整條不包含ASIMA的記錄
不等於: awk '$1 != "asima"' temp
小於: awk '{if ($1<$2) print $1 "is smaller"}' temp
設定大小寫: awk '/[Gg]reen/' temp 列印整條包含Green,或者green的記錄
任一字元: awk '$1 ~/^...a/' temp 列印第1域中第四個字元是a的記錄,符號’^’代表行首,符合’.’代表任一字元
或關係匹配: awk '$0~/(abc)|(efg)/' temp 使用|時,語句需要括起來
AND與關係: awk '{if ( $1=="a" && $2=="b" ) print $0}' temp
OR或關係: awk '{if ($1=="a" || $1=="b") print $0}' temp
2.4. awk內建變數:
ARGC |
命令列參數個數 |
NF |
瀏覽記錄的域個數 |
AGRV |
命令列參數排列 |
NR |
已讀的記錄數 |
ENVIRON |
支援隊列中系統內容變數的使用 |
OFS |
輸出域分隔字元 |
FILENAME |
awk瀏覽的檔案名稱 |
ORS |
輸出記錄分隔字元 |
FNR |
瀏覽檔案的記錄數 |
RS |
控制記錄分隔字元 |
FS |
設定輸入欄位分隔字元,同- F選項 |
NF |
瀏覽記錄的域個數 |
例: awk 'END {print NR}' temp 在最後列印已讀記錄條數
awk '{print NF,NR,$0} END {print FILENAME}' temp
awk '{if (NR>0 && $4~/Brown/) print $0}' temp 至少存在一條記錄且包含Brown
NF的另一用法: echo $PWD | awk -F/ '{print $NF}' 顯示目前的目錄名
2.5. awk操作符:
在awk中使用操作符,基本運算式可以劃分成數字型、字串型、變數型、域及數組元素
設定輸入欄位到變數名:
awk '{name=$1;six=$3; if (six=="man") print name " is " six}' temp
域值比較操作:
awk 'BEGIN {BASE="27"} {if ($4<BASE) print $0}' temp
修改數範圍取值:(原輸入檔案不會被改變)
awk '{if ($1=="asima") $6=$6-1;print $1,$6,$7}' temp
修改文本域:
awk '{if ($1=="asima) ($1=="desc");print $1}' temp
只顯示修改記錄:(只顯示所需要的,區別上一條命令,注意{})
awk '{if ($1=="asima) {$1=="desc";print$1}}' temp
建立新的輸出域:
awk '{$4=$3-$2; print $4}' temp
統計列值:
awk '(tot+=$3);END {print tot}' temp 會顯示每列的內容
awk '{(tot+=$3)};END {print tot}' temp 只顯示最後的結果
檔案長度相加:
ls -l|awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END{print "totKB:" tot}'
只列出檔案名稱:
ls -l|awk '{print $9}' 常規情況檔案名稱是第9域
2.6. awk內建字串函數:
gsub(r,s) 在整個$0中用s替代r
awk 'gsub(/name/,"xingming") {print $0}' temp
gsub(r,s,t) 在整個t中用s替代r
index(s,t) 返回s中字串t的第一位置
awk 'BEGIN {print index("Sunny","ny")}' temp 返回4
length(s) 返回s的長度
match(s,r) 測試s是否包含匹配r的字串
awk '$1=="J.Lulu" {print match($1,"u")}' temp 返回4
split(s,a,fs) 在fs上將s分成序列a
awk 'BEGIN {print split("12#345#6789",myarray,"#")"'
返回3,同時myarray[1]="12", myarray[2]="345", myarray[3]="6789"
sprint(fmt,exp) 返回經fmt格式化後的exp
sub(r,s) 從$0中最左邊最長的子串中用s代替r(只更換第一遇到的匹配字串)
substr(s,p) 返回字串s中從p開始的尾碼部分
substr(s,p,n) 返回字串s中從p開始長度為n的尾碼部分
2.7. printf函數的使用:
字元轉換: echo "65" |awk '{printf "%c\n",$0}' 輸出A
awk 'BEGIN {printf "%f\n",999}' 輸出999.000000
格式化輸出:awk '{printf "%-15s %s\n",$1,$3}' temp 將第一個域全部靠左對齊顯示
2.8. 其他awk用法:
向一行awk命令傳值:
awk '{if ($5<AGE) print $0}' AGE=10 temp
who | awk '{if ($1==user) print $1 " are in " $2 ' user=$LOGNAME 使用環境變數
awk指令碼命令:
開頭使用 !/bin/awk -f ,如果沒有這句話自含指令碼將不能執行,例子:
!/bin/awk -f
# all comment lines must start with a hash '#'
# name: student_tot.awk
# to call: student_tot.awk grade.txt
# prints total and average of club student points
# print a header first
BEGIN
{
print "Student Date Member No. Grade Age Points Max"
print "Name Joined Gained Point Available"
print"========================================================="
}
# let's add the scores of points gained
(tot+=$6);
# finished processing now let's print the total and average point
END
{
print "Club student total points :" tot
print "Average Club Student points :" tot/N
}
2.9. awk數組:
awk的迴圈基本結構
For (element in array) print array[element]
awk 'BEGIN {record="123#456#789";split(record,myarray,"#")}
END { for (i in myarray) {print myarray[i]} }
3.0 awk中自訂語句
一.條件判斷語句(if)
if(運算式) #if ( Variable in Array )
語句1
else
語句2
格式中"語句1"可以是多個語句,如果你為了方便Unix awk判斷也方便你自已閱讀,你最好將多個語句用{}括起來。Unix awk分枝結構允許嵌套,其格式為:
if(運算式)
{語句1}
else if(運算式)
{語句2}
else
{語句3}
[xifj@localhost nginx]# awk 'BEGIN{
test=100;
if(test>90)
{
print "very good";
}
else if(test>60)
{
print "good";
}
else
{
print "no pass";
}
}'
very good
每條命令語句後面可以用“;”號結尾。
二.迴圈語句(while,for,do)
1.while語句
格式:
while(運算式)
{語句}
例子:
[xifj@localhost nginx]# awk 'BEGIN{
test=100;
total=0;
while(i<=test)
{
total+=i;
i++;
}
print total;
}'
5050
2.for 迴圈
for迴圈有兩種格式:
格式1:
for(變數 in 數組)
{語句}
例子:
[xifj@localhost nginx]# awk 'BEGIN{
for(k in ENVIRON)
{
print k"="ENVIRON[k];
}
}'
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=zh_CN.GB2312
。。。。。。
說明:ENVIRON 是awk常量,是子典型數組。
格式2:
for(變數;條件;運算式)
{語句}
例子:
[xifj@localhost nginx]# awk 'BEGIN{
total=0;
for(i=0;i<=100;i++)
{
total+=i;
}
print total;
}'
5050
3.do迴圈
格式:
do
{語句}while(條件)
例子:
[xifj@localhost nginx]# awk 'BEGIN{
total=0;
i=0;
do
{
total+=i;
i++;
}while(i<=100)
print total;
}'
5050
以上為awk流程式控制制語句,從文法上面大家可以看到,與c語言是一樣的。有了這些語句,其實很多shell程式都可以交給awk,而且效能是非常快的。
break |
當 break 語句用於 while 或 for 語句時,導致退出程式迴圈。 |
continue |
當 continue 語句用於 while 或 for 語句時,使程式迴圈移動到下一個迭代。 |
next |
能能夠導致讀入下一個輸入行,並返回到指令碼的頂部。這可以避免對當前輸入行執行其他的操作過程。 |
exit |
語句使主輸入迴圈退出並將控制轉移到END,如果END存在的話。如果沒有定義END規則,或在END中應用exit語句,則終止指令碼的執行。 |