模式4种 | 操作主要4个 |
---|---|
/正则表达式/ | 变量或数组赋值 |
关系表达式 | 输出命令 |
模式匹配表达式 | 内置函数 |
BEGIN语句块、pattern语句块、END语句块 | 控制流语句 |
awk ‘BEGIN{ print “strat” } pattern{commands} END{ print “end” }’ file
echo -e "A line 1\nA line 2" | awk 'BEGIN{print "start"} {print } END{print "End"}'
输出:
start
A line 1
A line 2
End
#echo -e表示shell开启转义字符即\n表示换行
echo | awk '{var1="v1";var2="v2";var3="v3";print var1,var2,var3;}'
输出:
v1 v2 v3
echo | awk '{var1="v1";var2="v2";var3="v3";print var1"="var2"="var3;}'
输出:
v1=v2=v3
{}类似一个循环体,会对文件中的每一行进行迭代,通常变量初始化语句(如:i=0)以及打印文件头部的语句放入BEGIN语句模块;将打印的结果等语句放入END语句块中;
$n:当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段;
$0:这个变量包含执行过程中当前行的文本内容
FILENAME:当前输入文件的名
FS:字段分割度(默认是任何空格)
NF:表示字段数,在执行过程中对应与当前的字段数
NR:表示记录数,在执行过程中对应与当前的行号
OFMT:数字的输出格式(默认是%.6g)
OFS:输出字段分隔符(默认是一个空格)
ORS:输出记录分隔符(默认是一个换行)
RS:记录分割符(默认是一个换行)
实例4
echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print "Line No is:"NR,";NF:No of fields:"NF,";$0="$0,"$1="$1,"$2="$2,"$3="$3}'
#打印print以空格作为分割,输出结果以空格作为定界符
#print中""用作拼接,打印注释信息
#输出为:
Line No is:1 ;NF:No of fields:3 ;$0=line1 f2 f3 $1=line1 $2=f2 $3=f3
Line No is:2 ;NF:No of fields:3 ;$0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line No is:3 ;NF:No of fields:3 ;$0=line3 f6 f7 $1=line3 $2=f6 $3=f7
echo -e "line1 f2 f3\nline2 f4 f5" | awk '{print $0"\n"$NF,$(NF-1)}'
#NF当前行的字段数,NF-1就少了1个
#输出:
line1 f2 f3
f3 f2
line2 f4 f5
f5 f4
#打印每一行的内容以及第二个和第三个字段并统计行数
echo -e "lien 1 is 1\nline 2 is 2\nline 3 is me" > log.txt ; awk '{print $0"\n"$2,$3} END{print NR}' log.txt
#NR:记录数,对应当前的行数
#上面END语句块,在读入每一行时,awk会将NR更新为对应的行号,达到最后一行NR就是最后一行的行号
#seq 5产生1到5的所有整数, $1当前行的第一个字段内容,;表示该行语句结束类似c语言
#使用awk一定要注意格式是否正确,以及区分中英文
seq 5 | awk 'BEGIN{sum=0;print "总和:"} { print $1"+";sum+=$1} END{print "等于";print sum}'
VAR=1000
echo | awk -v VARIABLE=$VAR '{print VARIABLE}'
另一种传递变量的方式:变量直接使用空格分割符号作为awk的命令行参数,跟随在BEGIN、{}、和END语句块之后
var1="jhon"
var2="jhon2"
echo |awk '{print v1,v2}' v1=$var1 v2=$var2
输出:
jhon jhon2
当输入来自文件时使用:
awk '{print v1,v2}' v1=$var1 v2=$var2 log.txt
作为一种编程设计语言应具有的特点之一,awk支持多种运算,这些运算与c语言提供的基本相同。此外,awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等)和一些用于对字符串进行操纵(运算)的函数(length、substr等等),awk允许多种测试;
运算符 | 描述 |
---|---|
+ - | 加减 |
* / | 乘除 |
& | 求余数 |
+ - ! | 一元加,减和逻辑非 |
^ *** | 求幂 |
++ – | 增加或减少 |
awk 'BEGIN{a="b";print a,a++,++a}'
输出:
b 0 2
awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'
输出:
0 1
awk 'BEGIN{a="100testa";if(a ~ /^100*/){print "ok";}}'
输出:
ok
awk 'BEGIN{a=11;if(a>=9){print "ok";}}'
#输出ok
awk 'BEGIN{a="b";print a="b"?"ok":"err"}'
#输出ok
awk 'BEGIN{a="b";arr[0]="b";arr[1]="c";print (a in arr);}'
#输出0
#当记录行号除以2余1时,就会跳过当前行,print NR,$0也不会执行,下一行开始,再次判断等于2,就会执行下面的语句块print NR,$0
seq 5 > log.txt
awk 'NR%2==1{next}{print NR,$0}' log.txt
#输出
2 b
4 d
cat text.txt
web01[192.168.2.100]
httpd ok
tomcat ok
sendmail ok
web02[192.168.2.101]
httpd ok
postfix ok
web03[192.168.2.102]
mysqld ok
httpd ok
0
awk '/^web/{T=$0;next;}{print T":t"$0;}' test.txt
#next满足正则表达式执行前{},不满足执行后{}
#输出:
web01[192.168.2.100]:httpd ok
web01[192.168.2.100]:tomcat ok
web01[192.168.2.100]:sendmail ok
web02[192.168.2.101]:httpd ok
web02[192.168.2.101]:postfix ok
web03[192.168.2.102]:mysqld ok
web03[192.168.2.102]:httpd ok
web03[192.168.2.102]:0
当其左右无重定向符 | 或 <是:getline作用于当前文件,读入当前文件的第一行给其后跟的变量var或$0;注意由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的
#执行linux的date命令,并通过管道输给getline,然后再把输出结果赋给自定义变量out,并打印它:
awk 'BEGIN{ "date" | getline out; print out }' test
#执行shell的date命令,并通过管道输给getline,然后getline从管道中读取并将它赋值给out,split函数把变量out转化为数组mon,然后打印数组mon的第二个元素:
awk 'BEGIN{"date" | getline out;split(out,mon);print mon[2]}' test
#命令ls的输出传递给getline作为输入,循环使getline从ls的输出中读取一行,并把它打印。这里没有输入文件,因为BEGIN块在打开输入文件前执行,所以可以忽略输入文件
awk 'BEGIN{while("ls" | getline) print}'
#关闭文件:awk中允许在程序中关闭一个输入或输出文件;
close("filename")
#filename可以是getline打开的文件也可是stdin,或包含文件名的变量或getline使用的确切命令;或一个输出文件,可以是stdout等
#定向输出覆盖文件>
echo | awk '{printf{"hello world! jhon\n"} > "datafile"}'
#重定向输出末尾追加 >>
echo | awk '{print("hello world! jhon2\n") >> "datafile"}'
#分割符为: NF字段数:print $NF可以打印出一行中的最后一个字段
awk -F: '{print $NF}' /etc/passwd
#或在BEGIN语句块中使用OFS="定界符"设置输出字段的定界符
awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd
在linux awk的while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句退出,语法和c语言的类似,性能很快;
awk 'BEGIN{test=100;if(test>90){print "very good";} else if(test>60){print "good";}else{print "no pass";}}'
#while循环语句 i默认为0
awk 'BEGIN{test=100;total=0;while(i<=test){total+=i;i++} print total;} '
#输出
5050
#for循环
#格式1
for(变量 in 数组)
{语句}
awk 'BEGIN{for(k in ENVIRON){print k"="ENVIRON[k]}}'
#ENVIRON环境变量关联数组
#格式2
for(变量;条件;表达式)
{语句}
awk 'BEGIN{total=0;for(i=0;i<=100;i++){total+=i;}print total;}'
#输出5050
#do 循环
do
{语句} while(条件)
awk 'BEGIN{total=0;i=0;do {total+=i;i++;} while(i<=100) print total;}'
exit语句使主输入循环退出并将控制转移到END,如果存在END的话,如果没有定义END规则,或END中应用exit语句,则终止脚本的执行;
Array[1]="sun"
Array[2]="kai"
#字符串做数组下标索引:
Array["first"]="jhon"
Array["last"]="jhon2"
#读取数组的值
#使用print Array[1]会打印sun,使用print Array[first]会打印jhon
{for(item in array){print array[item]};} #输出的顺序是随机的
{for(i=1;i<=len;i++){print array[i]};}
awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}'
#length返回字符串以及数组长度,split进行分给字符串为数组,也会返回分割得到的数组长度
awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA)}'
#asort对数组进行排序,返回数组长度
#有序输出
awk 'BEGIN{info="it is a test"; tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
#注意数组下标是从1开始的,与c数组不一样
#无序输出
awk 'BEGIN{info="it not is a test"; split(info,tA," ");for(k in tA){print k,tA[k];}}'
#for....in输出,因为数组是关联数组,默认是无序的;
#错误的判断方法:
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if(tB["c"]!="1"){print "no found";};for(k in tB){print k,tB[k];}}'
no found
a a1
b b1
c
#注意,没有定义tB["c"],但其值为空,因为awk数组是关联数组,只要通过数组引用它的key,就会自动创建该序列
#正确的判断方法
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if("c" in tB){print "ok";};for(k in tB){print k,tB[k];}}'
a a1
b b1
#删除键值,通过delete array["key"]
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'
#输出 b b1
awk 'BEGIN{for(i=1;i<9;i++){for(j=1;j<=9;j++){tarr[i,j]=i*j;print i,"*",j,"=",tarr[i,j];}}}'
#可以通过array[k,k2]引用来获得数组内容
#另一种方法
awk 'BEGIN{for(i=1;i<9;i++){for(j=1;j<=9;j++){tarr[i,j]=i*j;}}for(m in tarr){split(m,tarr2,SUBSEP);print tarr2[1],"*",tarr2[2],"=",tarr[m];}}'
#多维数组必须使用split()函数来访问单独的下标分量
未完待续
awk参考