文本三劍客之awk
1.awk語法
awk的基本語法如下:
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }‘ file
第一句的語法是awk加上選項,加上程序部分,加上變量,最後是要操作的文件路徑
第二句的語法是awk加上選項,接一個-f,後面是程序部分,不過此處的程序不在是一串代碼,而是一個文件,這個文件的內容是程序代碼,後面是變量和要操作的文件名
程序代碼部分是需要用單引號或者雙引號引起來,這樣能夠將awk的代碼和shell語言分隔開。
BEGIN部分
BEGIN部分代碼是在程序執行過程中最先被執行的部分,是可以選擇執行的,他執行是在讀文件之前,所以單獨的一個BEGIN是不需要文件的,例如:
awk ‘BEGIN{print“hello world”}’
執行結果如下:
BEGIN主要用來打印生成表的表頭等其他語句。
pattern部分
pattern是對文件處理的部分,他會按照記錄一個一個的掃描,知道所以的記錄都被掃描過結束,pattern是程序中最重要的部分,他也是可以選擇執行的,如果沒有pattern部分,則默認執行{print},即打印文件中的每一行,讀取文件中的每一行都會執行該語句,例如:
awk ‘1‘ /etc/fstab
執行結果如下:
END部分
END部分語句是在讀至輸入流末尾時執行的語句,這部分代碼也是可以選擇執行的,比如打印所有行的分析結果這類的信息匯總,例如
awk ‘{print}END{print "hello world"}‘ /etc/fstab
執行結果如下:
2.分割符、域和記錄
awk執行時,由分隔符分隔的字段(域)標記$1,$2..$n稱為域標識,我們可以選擇打印輸出這些域的內容。例如
awk -F‘ ‘ ‘{print $1,$3}‘ /etc/fstab
執行結果如下:
$0為所有域,例如:
awk -F‘ ‘ ‘{print $0}‘ /etc/fstab
執行結果如下:
文件按記錄來進行執行awk操作,在shell中每一行稱為一條記錄,awk中可以指定特定的文件記錄分割符。在shell中$是引用變量,而在awk中$的作用是引用記錄中的第幾個片段。
省略action,則默認執行 print $0 的操作,如果程序代碼中的內容為空或0,是什麽都不會執行的,因為空也是0,如果是非0,就默認執行{print},例如:
awk -F‘ ‘ ‘0‘ /etc/fstab
執行結果如下:
-F選項可以指定記錄中域的分割符,可以是任何東西。
3.awk內置變量
1.FS:輸入字段分隔符,默認為空白字符,例如:
awk ‘{print $1" "$3}‘ /etc/fstab
執行結果如下:
我們設置輸入字段分隔符為/,例如:
awk -v FS=‘/‘ ‘{print $1" "$3}‘ /etc/fstab
執行結果如下:
因為FS是內置變量,所以在awk中可以引用,例如
awk -v FS=‘/‘ ‘{print $1FS$3}‘ /etc/fstab
執行結果如下:
2.OFS:輸出字段分隔符,默認為空白字符,復制出一部分password內容用來演示,例如:
awk -v FS=: -v OFS=# ‘{print $1,$3}‘ /app/passwd
執行結果如下:
","表示引用輸出字段分割符,默認是空格,當定義了OFS後就是OFS了。
3.RS:輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效,例如:
awk -v FS=: -v RS=‘nologin‘ ‘{print $1,$3}‘ /app/passwd
執行結果如下:
可以看出整個文件被nologin分割為5段,稱為5個記錄,然後每個記錄以:作為域分割符,取出第1個域和第3個域。原有的換行符不再作為輸入記錄分割符,但是仍舊有效,輸出的內容中依然可以換行,例如:
awk -v OFS=‘:‘ -v FS=: -v RS=‘sbin‘ ‘{print $1,$3}‘ /app/passwd
執行結果如下:
/nologin加換行符和daemon被作為第二個記錄的第一個域輸出,域之間以:作為分割符,2是第三個域的內容。
4.ORS:輸出記錄分隔符,輸出時用指定符號代替輸入記錄分割符,例如:
awk -v ORS=‘#‘ -v RS=‘/sbin‘ ‘{print}‘ /app/passwd
執行結果如下:
可以看到原來的輸入記錄分割符‘/sbin’在輸出時被#替換,原來的換行符還有效,只是不作為記錄分割符
5.NF:字段數量,例如:
awk -v FS=: -v RS=‘/sbin‘ ‘{print NF}‘ /app/passwd
執行結果如下:
記錄按“/sbin”分割,而字段或者域用:分割。
6.NR:記錄號,例如:
awk -v RS=‘/sbin‘ ‘END{print NR}‘ /app/passwd
記錄被“/sbin”分割,然後用END生成統計結果,一共有11條記錄
7.FNR:各文件分別計數,記錄號,例如:
awk -v RS=‘/sbin‘ ‘{print FNR};END{print NR}‘ /app/passwd /app/passwd
記錄以"/sbin"分割,兩次對/app/passwd計數,最後用END生成統計結果,共有22條。
8.FILENAME:當前文件名,例如:
awk ‘{print FILENAME}‘ /app/passwd
9.ARGC:命令行參數的個數,例如:
awk ‘END{print ARGC}‘ /app/passwd /etc/passwd
執行結果如下:
一共有三個參數,第一個是awk,第二個是/app/passwd第三個是/etc/passwd
10.ARGV:數組,保存的是命令行所給定的各參數,例如:
awk ‘END{print ARGV[0] }‘ /app/passwd /etc/passwd
打印命令行第一個參數,執行結果如下:
awk ‘END{print ARGV[ARGC-1] }‘ /app/passwd /etc/passwd
打印命令行的最後一個參數,執行結果如下:
4.自定義變量
自定義變量的方法如下:
awk -v test=123 ‘BEGIN{print test}‘
如上,定義了一個test變量,執行結果如下:
還可以在程序中定義變量,例如:
awk -v ‘test=134{print test,tooth;tooth=23}‘ /etc/fstab
執行結果如下:
5.格式化輸出
格式化輸出使用的是printf,當使用printf時,必須要為每一個輸出指定格式,例如:
awk -F: ‘{printf "UNAME:%-15s UID:%s\n",$1,$3}‘ /app/passwd
執行結果如下:
%s表示顯示字符串,-15表示左對齊15字符,\n代表換行,下面是常用的格式化控制符:
%c: 顯示字符的ASCII碼
%d: %i: 顯示十進制整數
%e: %E:顯示科學計數法數值
%f: 顯示為浮點數
%g: %G:以科學計數法或浮點形式顯示數值
%s: 顯示字符串
%u: 無符號整數
%%: 顯示%自身
還有一些修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f
-: 左對齊(默認右對齊) %-15s
+:顯示數值的正負符號 %+d
6.操作符
1.算術操作符
+加-減*乘/除%取余^乘方
-x轉換為負數
+x轉換為數值
2.賦值操作符
=, +=, -=, *=, /=, %=, ^=
++, --
3.邏輯操作符
&&邏輯與
||邏輯或
!邏輯非
4.比較操作符
==等於
!=不等於
>大於
>=大於等於
<小於
<=小於等於
5.模式匹配符
~:左邊是否和右邊匹配包含
!~:是否不匹配
例如:
awk -F: ‘$0 ~ /root/ {print $1}‘ /etc/passwd
執行結果如下:
awk支持正則表達式,例如
awk -F: ‘$0 ~ "^root" {print $1}‘ /etc/passwd
6.三目表達式
三目表達式的格式如下:
判斷?語句1:語句2
最開始先進行判斷,如果判斷結果為真,則執行語句1,如果判斷結果為假,則執行語句2,例如:
awk ‘BEGIN{1>3?a=1:a=3;print a}‘
執行結果如下:
7.awk action
1.awk循環
while循環
循環在條件為真開始循環,在條件為假時結束循環,例如:
awk ‘BEGIN{i=1;while(i<10){ print i;i++}}‘
執行結果如下:
for循環
循環在滿足for的條件時開始循環,在不滿足for條件時結束循環,例如:
awk ‘BEGIN{for(i=1;i<10;i++)print i}‘
執行結果如下:
2.awk選擇
if選擇
如果滿足if後面條件,則執行之後的語句,否則不執行,進行其他的if判斷,最多有一個if被執行,例如:
awk -v i=9 ‘BEGIN{if(i<=5){print "小於等於5"}else if(i>5 && i<=10){print "大於5小於等於10"}else{print "大於10"}}‘
執行結果如下:
3.awk控制
continue控制
continue控制是結束當前這一次循環,直接進行下一次循環,例如:
awk ‘BEGIN{i=0;while(i<10){i++;if(i==5){continue} print i}}‘
執行結果如下:
當執行到i=5時,結束了循環,沒有輸出5,繼續下一次循環,即i=6的循環。
break控制
break控制是結束當前這一層循環,返還到上一級,例如:
awk ‘BEGIN{i=0;while(i<10){i++;if(i==5){break} print i}}‘
當執行到i=5時,結束了當前循環,退出當前的循環,沒有再進行打印5的操作以及之後的循環。
4.awk數組
我們常常用數組來看文件中某一列內容的重復次數,例如:
awk -F: ‘{line[$7]++}END{for(i in line){print i,line[i]}}‘ /etc/passwd
執行結果如下:
5.awk函數
awk函數一般是寫在一個文件中的,當需要時調用這個函數文件,例如:
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
執行結果如下:
6.awk腳本
在awk中可以用system調用shell命令,例如:
awk ‘BEGIN{score=100; system("echo your score is " score) }‘
執行結果如下:
我們可以用執行腳本的方法來執行awk例如:
#!/bin/awk –f
{if($3>=1000)print $1,$3}
將上面代碼寫入文件:
加上執行權限,並執行,結果如下:
文本三劍客之awk