和sed一样,awk也是逐行扫描文件的,从第一行到最后一行,寻找匹配特定模板的行,并在这些行上运行“选择”动作。如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。如果一个动作没有模板,所有被动作指定的行都被处理。
1. awk的基本格式:
/> awk ‘pattern’ filename
/> awk ‘{action}’ filename
/> awk ‘pattern {action}’ filename
具体应用方式分别见如下三个用例:
/>cat expless 1 zhang3 4321 1/2/36 76512 2 li4 7652 10/14/33 67123 3 wang5 3219 4/21/50 21214 4 zhao6 8900 12/8/44 98761
#打印所有包li4的行
/>awk ‘/li4/’ expless 2 li4 7652 10/14/33 67123
#打印文件中的第2个字段,这个域在每一行的开始,缺省由空格或其它分隔符。
/>awk ‘{print $2}’ expless zhang3 li4 wang5 zhao6
#打印包含模板zhang3的行的第一、第二个域字段。
/>awk -F ” ” ‘/zhang3/{print $1,$2}’ expless 1 zhang3
2. awk的输出格式:
awk中同时提供了print和printf两种打印输出的函数,其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。下面给出基本的转码序列:
转码 含义
\n 换行
\r 回车
\t 制表符
#从date中选择年和时间输出,并实用制表符间隔
/>date | awk ‘{print “Year: “$6 “\tTime: “$5}’ Year: CST Time: 11:40:49 />awk ‘/zhang3/{print $2″,\tWelcome to http://www.icesr.com!”}’ expless zhang3, Welcome to http://www.icesr.com!
#在打印数字的时候你也许想控制数字的格式,我们通常用printf来完成这个功能。awk的特殊变量OFMT也可以在使用print函数的时候,控制数字的打印格式。它的默认值是”%.6f”—-小数点后面6位将被打印。
/> awk ‘BEGIN { OFMT=”%.3f”; print 14E-3, 1.414123123}’ 0.014 1.414
下面介绍一下功能更为强大的printf函数,其用法和c语言中printf基本相似。下面我们给出awk中printf的格式化说明符列表:
格式化说明符 功能 示例 结果
%c 打印单个ASCII字符。 printf(“The character is %c.\n”,x) The character is A.
%d 打印十进制数。 printf(“The boy is %d years old.\n”,y) The boy is 15 years old.
%e 打印用科学记数法表示的数。 printf(“z is %e.\n”,z) z is 2.3e+01.
%f 打印浮点数。 printf(“z is %f.\n”,z) z is 2.300000
%o 打印八进制数。 printf(“y is %o.\n”,y) y is 17.
%s 打印字符串。 printf(“The name of the culprit is %s.\n”,$1); The name of the culprit is Bob Smith.
%x 打印十六进制数。 printf(“y is %x.\n”,y) y is f.
# %-20s表示保留20个字符的空间,同时左对齐。
/>echo “icesr.com” | awk ‘{printf “|%-20s|\n”, $1}’ |icesr.com
|
# %-20s表示保留20个字符的空间,同时右对齐。
/>echo “icesr.com” | awk ‘{printf “|%20s|\n”, $1}’ | icesr.com| />awk ‘{printf “UID is %2d Name is %-15s\n”, $1,$2}’ expless UID is 1 Name is zhang3 UID is 2 Name is li4 UID is 3 Name is wang5 UID is 4 Name is zhao6
3. awk中的记录和域:
# awk中默认的记录分隔符是回车,保存在其内建变量ORS和RS中。$0变量是指整条记录。
/>awk ‘{print $0}’ expless 1 zhang3 4321 1/2/36 76512 2 li4 7652 10/14/33 67123 3 wang5 3219 4/21/50 21214 4 zhao6 8900 12/8/44 98761
#变量NR(Number of Record),记录每条记录的编号。
/>awk ‘{print $0,NR}’ expless 1 zhang3 4321 1/2/36 76512 1 2 li4 7652 10/14/33 67123 2 3 wang5 3219 4/21/50 21214 3 4 zhao6 8900 12/8/44 98761 4
#将expless用空格分隔变成实用”:”分隔并存为expless1文件中
/>awk ‘{OFS = “:”};{print $1,$2,$3,$4,$5}’ expless >expless1 />cat expless1 1:zhang3:4321:1/2/36:76512 2:li4:7652:10/14/33:67123 3:wang5:3219:4/21/50:21214 4:zhao6:8900:12/8/44:98761
#在expless中打印出含zhang3的行,注意-F是指定分隔符
/>awk -F: ‘/zhang3/{print $0}’ expless1 1:zhang3:4321:1/2/36:76512
#对于awk而言,其模式部分将控制这动作部分的输入,只有符合模式条件的记录才可以交由动作部分基础处理,而模式部分不仅可以写成正则表达式(如上面的例子),awk还支持条件表达式,如:
/>awk -F: ‘$5>70000 {print}’ expless1 1:zhang3:4321:1/2/36:76512 4:zhao6:8900:12/8/44:98761
#其中”{}”内需要执行多个动作的时候,可以使用”;”分隔或者直接换行分隔
#模式和动作一般是捆绑在一起的。需要注意的是,动作是花括号内的语句。模式控制的动作是从第一个左花括号开始到第一个右花括号结束,如下:
/> awk -F: ‘$5>70000&&/zhang3/ {print}’ expless1 1:zhang3:4321:1/2/36:76512
4. 匹配操作符:
” ~ ” 用来在记录或者域内匹配正则表达式。
#匹配名字为zhang3或者Zhang3的行
/>awk -F ” ” ‘$2~/[Zz]hang3/{print $1,$2}’ expless 1 zhang3
#匹配名字不匹配zhang3或者Zhang3的行
/>awk ‘ $2 !~/[Zz]hang3/{print $1,$2}’ expless 2 li4 3 wang5 4 zhao6
5. awk的基本应用实例:
/>cat passwd 1root:x:0:0:root:/root:/bin/bash 2bin:x:1:1:bin:/bin:/sbin/nologin 3daemon:x:2:2:daemon:/sbin:/sbin/nologin 4adm:x:3:4:adm:/var/adm:/sbin/nologin 5lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6sync:x:5:0:sync:/sbin:/bin/sync
#打印出以4adm开头的行
/>awk ‘/^4adm/{print}’ passwd 4adm:x:3:4:adm:/var/adm:/sbin/nologin />awk ‘/^[135]/’ passwd #打印出所有以1,3,5开头的行 1root:x:0:0:root:/root:/bin/bash 3daemon:x:2:2:daemon:/sbin:/sbin/nologin 5lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin />awk ‘/(root|adm)/’ passwd #打印出含root或adm的行 1root:x:0:0:root:/root:/bin/bash 4adm:x:3:4:adm:/var/adm:/sbin/nologin
#从passwd文件中打印出以数字1-4开头后跟adm或者lp的行中的第1和第6域,并使用” && “作为域分隔符号
/>awk -F: ‘{OFS = ” && “};$1~/^[1-4](adm|lp)/{print $1,$6}’ passwd 4adm && /var/adm
未经允许不得转载:SRE空间 » bash脚本中awk基础实用功能
评论前必须登录!
注册