awk命令詳解
2009年03月31日 星期二 22:22
AWK指令詳解
1. 命令簡述:
awk將每個輸入行識別成一條記錄,而將那一行上的每個單詞域識別成一個字段
2. 命令選項:
-F 指定分隔符
NF 單行最後一個分段
NR 行數
&& 等同 AND 語句兩邊必須同時匹配爲真
|| 等同 OR 語句兩邊同時或其中一邊匹配爲真。
! 求逆
ARGC 支持命令行中傳入awk腳本的參數個數。
ARGVARGC 參數排列數組,其中每一元素表示爲ARGV[n],n爲期望訪問的命令行參數。
ENVIRON 支持系統設置的環境變量,例如ENVIRON[“EDITOR”] =“Vi”
FILENAME 支持a w k腳本實際操作的輸入文件
FNR 支持a w k目前操作的記錄數。其變量值小於等於N R。
FS 用來在a w k中設置域分隔符,與命令行中- F選項功能相同,例:F S = ","
NF 支持記錄域個數,在記錄被讀之後再設置
OFS 允許指定輸出域分隔符,缺省爲空格。如果想設置爲#,寫入O F S = " # "
ORS 爲輸出記錄分隔符,缺省爲新行( \ n)
RS 記錄分隔符,缺省爲新行( \ n )
gsub(r,s) 在整個$ 0中用s替代r,r爲原內容,s爲新內容,r可爲/正則/
gsub(r,s,t) 在整個t中用s替代r, r爲原內容,s爲新內容,r可爲/正則/
index(s,t) 返回s中字符串t的第一位置
length(s) 返回s長度
match(s,r) 測試s是否包含匹配r的字符串
split(s,a,fs) 以fs爲分隔符將s分成序列數組a
sprint(fmt,exp) 返回經f m t格式化後的e x p
sub(r,s) 將$ 0第一個r替換爲s ,r可爲/正則/
sub(r,s,t) 將域t中的第一個r替換爲s ,r可爲/正則/
substr(s,p) 返回字符串s中從p開始的後綴部分
substr(s,p,n) 返回字符串s中從p開始長度爲n的後綴部分
rand() 產生0到1之間的符點小數
Printf()
- 左對齊
width 域的步長,用0表示0步長
. prec 最大字符串長度,或小數點右邊的位數
%c ASCII字符
%d 整數
%e 浮點數,科學記數法
%f 浮點數,例如(1 2 3 . 4 4)
%g awk決定使用哪種浮點數轉換e或者f
%o 八進制數
%s 字符串
%x 十六進制數
3. 引用文件list.txt:
54786542:13744232156
360565687:15026736523
360565687:13597572727
100000:13898754555
100000:13898754555
1510121:155554215544:TTTa
baoping 207
1986 2009
1986 2007
baoping 2007
Malist
dj121M112d12nmm
tete
4. 實例說明:
awk '/^/' list.txt 匹配包含^的行,即顯示全文 awk '/$/' list.txt 匹配包含$的行,即顯示全文 awk '/./' list.txt 匹配包含^的行,即顯示全文 awk '/.*/' list.txt 匹配包含任意字符的行,即顯示全文 awk '{ print $1 }' list.txt 顯示list.txt中每行第一串字符串 awk '/M/' list.txt 顯示包含字符M所有的行 awk '/M/ { print $1 }' list.txt 顯示包含M的行的第一串字符串 awk '/M/ {print "TT",$1}' list.txt 匹配包含M前面添加顯示TT空格 awk -F, '{ print $1; print $2}' list.txt 逗號爲分隔符,無第二串則換行 awk '{print NF}' list.txt 顯示默認分隔符最後一個分段$數置 awk '{print $NF}' list.txt 顯示最後一分段的值 awk '{n++}END{print n" line"}' list.txt 統計文本內容行數 awk -F: '{if($2~/15026736523/) print $0}' list.txt 匹配第二域,並顯示該記錄 awk '$0!~/15026736523/' list.txt 不匹配並顯示該記錄 awk '$0 ~ /15026736523/ {print $0 }' list.txt 匹配手機號,並顯示該記錄 awk -F: '$2=="15026736523" {print $0 }' list.txt 精確匹配$2的值 awk -F: '{if($2=="15026736523")print $0}' list.txt 精確匹配$2的值 awk -F: '{if($1 < $2) print $0}' list.txt 判斷$1小於$2的記錄並print awk '/[Mm].*/' list.txt 匹配M.*或者m.* awk -F: '$1 ~ /^…i/ {print $0}'list.txt 匹配第四個字符爲i的行並顯示 awk -F: '$1 ~ /(360|332)/ {print $0}'list.txt 匹配360和332的行.效果同[] awk -F: '$1=="360565687" && $2=="15026736523"' list.txt 同時要符合條件,交集 awk -F: '{if ($1~/360/ || $2 ~/150/)print $0}' list.txt 匹配任何一個,並集 awk '{if (NR>0 && $1~/3605656/)print $0}' list.txt 匹配if條件 awk 'BEGIN{var="200"} {if ($1<var) print $0}' list.txt 利用begin賦值 awk '{if($1=="baoping"){$2=$2+1};print $2}' list.txt 算術運算 awk '{if($1=="baoping") $2="1986";print $2}' list.txt 重新賦值並顯示所有$2 awk '{if($1=="baoping") {$2="1986";print $2}}' list.txt 重新賦值並顯示單個$2 awk 'BEGIN{print "To"}{if($1<$2) {$2=$2-$1;print $0}}' list.txt 結果1986 23 awk '{(tot+=$2)}; END{print "total number:" tot}' list.txt 計算所有$2列的和 ls -l | awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END {print "KB:" tot}' 大小和 awk 'gsub("2007","2009",$0){print $0}' list.txt 將2007改爲2009並顯示 awk 'BEGIN {print index("150","5")}' 顯示2,數所在的位數 awk '$1=="baoping" {print length($1)" "$1}' list.txt 顯示結果7 baoping,字符長度 awk '$1=="baoping" {print match($2,"7")}' list.txt 相同字符首位置,本例4 awk 'BEGIN {print split("1#2#3#4",shuzu,"#")}' 結果爲數組有4個元素shuzu[] echo az bg cde|awk '{sub(/[ab]/,"g",$2);print $2}' sub用正則表達式替換,結果gg awk -F"[ :]" '{ print $1 }' list.txt 同時使用兩個分隔符 awk '$1=="1986" {print substr($2,1,3)}' list.txt 顯示匹配的$2從1後3個字符 awk '{print substr($1,3)}' list.txt 顯示每行第3字符後的字符 awk 'BEGIN{STR="hello"}END{print substr(STR,4)}' list.txt 從第四位開始即lo echo "Stand-by" | awk '{print length($0)}' 統計變量字符個數 STR="mydoc.txt"; echo $STR|awk '{print substr($STR,1,5)}' 結果mydoc echo "65" | awk '{printf "%c\n",$0}' 以ASCII碼顯示65即A awk 'BEGIN{printf "%c\n",65}' 以ASCII碼顯示65 awk 'BEGIN{printf "%f\n",999}' 以符點數顯示結果999.000000 awk -F"[: ]" '{printf "%-15s %s\n",$1,$2}' list.txt $1與$2分別1 5個字符長度 awk '{if ($1<QQ) print $0}' QQ=360565687 list.txt 傳遞參數給awk使用 awk 'BEGIN{QQ=360565687}{if ($1<QQ) print $0}' list.txt 傳遞參數給awk使用 awk 'BEGIN{FS=":"}{print $1,"\t",$2}' list.txt 此方式必須在begin指定分隔符 awk 'NF!=MAX{print("line "NR" does not "MAX"")}' MAX=2 list.txt 如域數不等於2則顯示,C風格 awk 'BEGIN{print (1+2.5)*3}' 結果10.5,shell不能比較浮點數 awk 'BEGIN {split("123#456#789",my,"#");print my[1]}' 此時my[1]爲第一個元素 awk -F: '{a[$1]=a[$1]"\n"$2;v[$1]++}END{for ( i in a )print "["i"]",v[i],a[i]}' qq.txt //顯示數組中的key其中i即key awk '{for(i=1;i<100;i++){if($i ~/UN=/){print $2"\t"substr($5,2)" "$8" "$i}}}' kkk.txt //使用標準風格的for語句 awk 'a=0;{for(i=1;i<=NF;i++)a+=$i;b=a/NF;print b}' 1.txt //求a.txt每行的平均值 awk '{for(i=1;i<=NF;i++)a[i]+=$i}{if(NR==3){for(i=1;i<=NF;i++){print a[i]/NR}}}' 1.txt
awk 求和
在Shell中,我們可以用awk實現按列求和的功能,非常簡單。看下面的例子:
1.簡單的按列求和
[linux@test /tmp]$ cat test
123.52
125.54
126.36
[linux@test /tmp]$ awk '{sum += $1};END {print sum}' test
375.42
2.對符合某些條件的行,按列求和
[linux@test /tmp]$ cat test
aaa 123.52
bbb 125.54
aaa 123.52
aaa 123.52
ccc 126.36
對文件test中 第一列爲aaa的行求和
[linux@test /tmp]$ awk '/aaa/ {sum += $2};END {print sum}' test
370.56
awk 處理文本還是很方便的。
# cat lastlog
1008520650 天津 http://www.aibang.com/abc/a.jpg 0.015
1008522118 天津 http://www.aibang.com/abc/a.jpg 0.015
1008520646 天津 http://www.aibang.com/abc/a.jpg 0.015
1999853994 瀋陽 http://www.aibang.com/abc/a.jpg 0.015
1008520650 天津 http://www.aibang.com/abc/a.jpg 0.015
1008522118 天津 http://adad.ada.con/da 0.018
1008520646 天津 http://adadad/dad/dd.abc 0.016
1999853994 瀋陽 http://www.sohu.com/abc/d.jif 1.14
# cat lastlog|grep "天津"|awk '{print$NF}' |awk '{sum += $1};END{print sum}'
0.094
我的NF是最後一個字段
#awk '/天津/{sum += $NF};END {print sum}' lastlog