內(nèi)容:
awk[options]'program'var=valu file
-f programfilevar=value file…
'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...
awk程序通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成
部基本格式:awk [options]'program'file..
statements;......}
pattern:分決定動作語句何時觸發(fā)及觸發(fā)事件
stattements:對數(shù)據(jù)進行處理,放在{}內(nèi)指明printprintf
啊我可執(zhí)行時,由分割符分隔的字段(域)標記$1,$2..$n稱為域標識。$0為所有域
?第一步:執(zhí)行BEGIN{action;… }語句塊中的語句
?第二步:從文件或標準輸入(stdin)讀取一行,然后執(zhí)行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
?第三步:當讀至輸入流末尾時,執(zhí)行END{action;…}語句塊
?BEGIN語句塊在awk開始從輸入流中讀取行之前被執(zhí)行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通??梢詫懺贐EGIN語句塊中
?END語句塊在awk從輸入流中讀取完所有的行之后即被執(zhí)行,比如打印所有行的分析結(jié)果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊
(2)輸出的各item可以字符串,也可以是數(shù)值;當前記錄的字段、變量或awk的表達式
tail??–3 /etc/fstab|awk‘{print $2,$4}’
-F : '{sum+=$3}END{print sum}' /etc/passwd

awk-vFS=':''{print $1,FS,$3}'/etc/passwd(以:為分隔符取/etc/passwd第一第三字段)
awk–F:'{print $1,$3,$7}’ /etc/passwd
awk-v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’
/etc/passwd
awk -v RS=";"'{print $1,$3,$4}' f1(以分號為記錄的分隔符,取記錄的第1,3,4字段)

awk-vORS='##$#' {print $1,#$3,$4}f1
awk-F:'{print?NF}' ??/etc/fstab,引用內(nèi)置變量不用$
awk-F: '{print $(NF-1)}' ? ? /etc/passwd
awk ? ?'{print NR}' ? /etc/fstab(沒有意義,只是輸出行號)
awk ? -F:'{print NF,$0}' ? ?/etc/passwd(給/etcpasswd加入行號)

awk '{print FILENAME}’ /etc/fstab
awk ?'BEGIN{print ARGC}' ? ?/etc/fstab/etc/inttab

ARGV:數(shù)組,保存的是命令行所給定的各參數(shù)
awk ? 'BEGIN{print ARGV[0]}'f1test第一個參數(shù)為awk

awk ? 'BEGIN{printARGV[1],ARGV[2]}'test f1 ?顯示第二第三個參數(shù)

awk ? 'BEGIN{printARGV[2]}' ? test ?f1
awk ? 'BEGIN{printARGV[ARGC-1]}' ?test f1兩都表示第三被參數(shù)

awk ?-v test='hello gawk' ? '{print test}' /etc/fstab
awk ?-v test='hello gawk' ? 'BEGIN{print test}'
awk ?'BEGIN{test="hello,gawk";printtest}'
awk ? ?–F: ?'{sex=“male”;print$1,sex,age;age=18}'? ??/etc/passwd
cat ? awk ?script? {print script,$1,$2}
awk-F: -f awkscriptscript=“awk” /etc/passwd
格式化輸出:printf"FORMAT",item1,item2
5)別忘了FORMAT與item1之間有一個逗號:"FORMAT",item1
%d, %i:顯示十進制整數(shù)
%g, %G:以科學計數(shù)法或浮點形式顯示數(shù)值
%s:顯示字符串(常用)
#[.#]:第一個數(shù)字控制顯示的寬度;第二個#表示小數(shù)點后精度,%3.1f
awk ?-F: ? '{printf"%s",$1}' ?/etc/passwd不會自動換行(不加換行符感覺很亂),需要顯式給出換行控制符,\n
?awk ?-F: ?'{printf"%s\n",$1}' ?/etc/passwd ?加了換行符
初學者的錯誤:

awk ?-F: ?'{printf "%-20s %10d\n",$1,$3}' ? ?/etc/passwd

?awk ?-F: ?'{printf "Username: "%s\n",$1}' ? /etc/passwd("%s\n"與$1別忘了加逗號)
?awk-F:'{printf“Username: %s,UID:%d\n",$1,$3}'
?awk -F: '{printf"Username:??%15s,UID:%d\n",$1,$3}' ?/etc/passwd

寫成自定義格式是不要把printf寫成pint下面的就是這樣的錯誤

x/y, x^y, x%y
/=, %=, ^=
>=, <, <=
awk–F: '$0 ~ /root/{print $1}‘ /etc/passwd
?awk –F:? '$3>=0 && $3<=1000 {print $1}' /etc/passwd
?awk -F: '$3==0? || $3>=1000 {print $1}' /etc/passwd
?awk -F:?'!($3==0){print $1}' /etc/passwd
?awk -F:??'!($3>=500) {print $3}' ?/etc/passwd
函數(shù)調(diào)用:function_name(argu1, argu2, ...)
條件表達式(三目表達式):
selector?if-true-expression:if-false-expression
邏輯:如果selector成立執(zhí)行if-true-exprssione的內(nèi)容,否則執(zhí)行:if-false-expression的內(nèi)容。?與:為固定格式造抄
?示例:用awk顯示/etc/passwd中的系統(tǒng)用戶和普通用戶
awk -F: '{$3>=500?usertype="Common?User":usertype="Sysadmin or
SysUser";printf"%-15s:%-s\n",$1,usertype}' /etc/passwd


PATTERN:根據(jù)pattern條件,過濾行,在處理
2)/regular expression/僅處理能夠模式匹配到的行,需要用/ /括起來
awk ? '/^UUID/{print $1}' ?/etc/fstab
awk ? '!/^UUID/{print $1}' ?/etc/fstab
3) relational expression:關(guān)系表達式,結(jié)果為“真”才會被處理
1)如果沒有指定:為空模式,匹配每一行(可以理解成4后面的描述)
4)如果PATTERN沒有{action},說明省略{print $0},表示輸出匹配到的整行(記錄)如下:
awk ?-F: 'i=1;j=1{printi,j}'/etc/passwdi=1后面省略了{print $0}所以先輸出整行,在輸出i,j的值

awk '!0'/etc/passwd!0為1,1表示匹配整行,沒有動作{action}表示輸出整行,連起來表示輸出整行


awk -F: '$NF ~/bash$/{print#$1,$NF}'/etc/passwd/bash$/是正則表達式

4.4) line? ranges:行范圍
startline,endline:/pat1/,/pat2/不支持直接給出數(shù)字格式
awk -F:? '/^root\>/,/^nobody\>/{print $1}' ? /etc/passwd
awk-F:? '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
BEGIN/END模式
BEGIN{}:僅在開始處理文件中的文本之前執(zhí)行一次
awk -F : 'BEGIN {print "USER USERID"} {print
$1":"$3} END{print "end file"}' /etc/passwd
?awk -F : '{print "USER USERID“;print $1":"$3}? END{print "end file"}' /etc/passwd
?awk -F: 'BEGIN{print " USER UID \n---------------"}{print?$1,$3}' /etc/passwd
.............................................................
seq 10 |awk ‘i=0’i=0為假不符合條件,不執(zhí)行
seq 10 |awk ‘i=1’i=1為真,符合條件,執(zhí)行。動作沒有指定:為空模式,匹配每一行
seq 10 | awk '{i=!i;print i}‘為命令seq 10 | awk 'i=!i‘中i的值
seq 10 | awk '!(i=!i)'因為i沒有賦值所以i=0當i=0是!0為1,!(i=1)為0不執(zhí)行,過后i=1
(i=!1)i=0, !(i=0)為1,執(zhí)行...
?seq 10 |awk -v i=1 'i=!i'i=1,賦值初始化,只執(zhí)行一次,i=!1 ,i=0,為假,不執(zhí)行,i=0,i=!0,i=1,為真執(zhí)行,。。。
if-else語法:if(condition){statement;...}[else statement]
if(condition1){statement;...}else
if (condition2){statement2}else {statement3}


seq10 |awk ‘i=0’i=0為假不符合條件,不執(zhí)行

seq 10 |awk 'i=1' ?i=1為真,符合條件,執(zhí)行。動作沒有指定:為空模式,匹配每一行


seq 10 | awk '{i=!i;print i}‘為命令seq 10 | awk 'i=!i‘中i的值

seq 10 | awk '!(i=!i)'因為i沒有賦值所以i=0當i=0是!0為1,!(i=1)為0不執(zhí)行,過后i=1
(i=!1)i=0, !(i=0)為1,執(zhí)行...

?seq 10 |awk -v i=1 'i=!i'i=1,賦值初始化,只執(zhí)行一次,i=!1 ,i=0,為假,不執(zhí)行,i=0,i=!0,i=1,為真執(zhí)行,。。。

awk控制語句:
if-else語法:if(condition){statement;...}[else statement]
if(condition1){statement;...}else
if (condition2){statement2}else {statement3}
awk ?-F: '{if($3>=1000)print $1,$3}' ?/etc/passwd??
awk ?-F: '{if($NF=="/bin/bash") print $1}'??/etc/passwd
awk'{if(NF>5) print $0}' /etc/fstab
awk-F: '{if($3>=1000) {printf"Common user:
%s\n",$1} else {printf"root or Sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($3>=1000) printf "Common user:
%s\n",$1;
else printf "root or Sysuser: %s\n",$1}'
/etc/passwd
$1}'|awk'$NF>=80{print $1,$5}‘
awk'BEGIN{ test=100;if(test>90){print "very
good"}
"good"}else{print "no pass"}}'
語法:while(condition){statement;}
條件“真”,進入循環(huán);條件“假”,退出循環(huán)
awk'/^[[:space:]]*linux16/{i=1;while(i<=NF)
{print $i,length($i); i++}}' /etc/grub2.cfg
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10)
{print $i,length($i)}; i++}}' /etc/grub2.cfg
?語法:do {statement;…}while(condition)
?awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print
total}‘
語法:for(expr1;expr2;expr3) {statement;…}
for(variable assignment;condition;iterationprocess)
語法:for(varin array) {for-body}
awk'/^[[:space:]]*linux16/{for(i=1;i<=NF;i++)
{print $i,length($i)}}' /etc/grub2.cfg
total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
?time(total=0;for i in {1..10000};do
total=$(($total+i));done;echo $total)
?time(for ((i=0;i<=10000;i++));do let
total+=i;done;echo $total)

{case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;
...; default: statementn}
?awk ?'BEGIN {sum=0;for(i=1;i<=100;i++)
提前結(jié)束對本行處理而直接進入下一行處理(awk自身循環(huán))
awk -F: '{if($3%2!=0) next; print $1,$3}'??/etc/passwd
awk數(shù)組
?關(guān)聯(lián)數(shù)組:array[index-expression]
?(2)如果某數(shù)組元素事先不存在,在引用時,awk會自動創(chuàng)建此元素,并將其值初始化為“空串”
?若要判斷數(shù)組中是否存在某元素,要使用“index in array”格式進行遍歷
'BEGIN{weekdays["mon"]="Monday";
weekdays["tue"]="Tuesday";print
weekdays["mon"]}‘
?awk '{!arr[$0]++;print $0, arr[$0]}' dupfile
awk數(shù)組
?若要遍歷數(shù)組中的每個元素,要使用for循環(huán)
?awk'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]
="Tuesday";for(iin weekdays) {print
weekdays[i]}}‘
?netstat-tan | awk'/^tcp/{state[$NF]++}END
{for(i in state) { print i,state[i]}}'
?awk'{ip[$1]++}END{for(iin ip) {print i,ip[i]}}'
/var/log/httpd/access_log
awk -F : '{line[$7]++}END{for(i in line){ print?i,line[i]}}' /etc/passwd
其中因為line[$7]沒有賦值默認為0,遍歷中i代表數(shù)組line的下標為$7,line[i]為為line[$7]為次數(shù)

awk '/^tcp/{line[$NF]++}END{for(i in line){printi,line[i]}}' ?f1.log
netstat -nt | awk -F '[[:space:]:]+''/^tcp/{ip[$6]++}END{for(i in ip){printi,ip[i]}}'
netstat -tn | awk??'/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
awk'BEGIN{srand(); for (i=1;i<=10;i++)print
int(rand()*100) }'
直接寫隨機數(shù)是錯誤的,它需要種子srand()才能生成隨機數(shù)
?sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內(nèi)容,并將第一個匹配的內(nèi)容替換為s
echo "2008:08:08 08:08:08" | awk'sub(/:/,“-",$1)'
?gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內(nèi)容,并全部替換為s所表示的內(nèi)容
awk‘gsub(/:/,“-",$0)'
?split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結(jié)果保存至array所表示的數(shù)組中,第一個索引值為1,第二個索引值為2,…
awk ?'/^tcp\>/{split($5,ip,":");count[ip[1]]++}
END{for (iin count) {print i,count[i]}}'
system命令
?空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用""引用起來。
awk BEGIN'{system("hostname") }'
awk'BEGIN{score=100; system("echo your score is
" score) }'
?將awk程序?qū)懗赡_本,直接調(diào)用或執(zhí)行