jyj00 2020-01-09
awk:格式化文本输出
gawk - pattern scanning and processing language
awk:gawk的符号链接 基本用法:gawk [options] ‘program‘ FILE program:PATTERN {ACTION STATEMENTS} 语句之间用分号分隔 print,printf 选项: -F: 指明输入时用到的字段分隔符; 默认空格 -v:var=value :自定义变量 变量名必须以字母或_开头 echo $变量名
1、print
print item1,item2,...
要点: (1)逗号分隔符; (2)输出的个item可以是字符串,也可以是数字;当前记录的字段、变量或awk的表达式 (3)如省略item,相当于print $0 练习模板: cat > passwd<<EOF root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin EOF
案例1:打印用户名和对应的shell
[ ~]# awk -F":" ‘{print $1,$7}‘ passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin operator /sbin/nologin
//添加制表符 [ ~]# awk -F":" ‘{print $1 "\t" $7}‘ passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin operator /sbin/nologin
案例2:打印用户名及对应的uid和gid
[ ~]# awk -F":" ‘{print "用户是:" $1 "\t 用户uid:" $3 "\t 用户gid:" $4}‘ passwd 用户是:root 用户uid:0 用户gid:0 用户是:bin 用户uid:1 用户gid:1 用户是:daemon 用户uid:2 用户gid:2 用户是:adm 用户uid:3 用户gid:4 用户是:lp 用户uid:4 用户gid:7 用户是:sync 用户uid:5 用户gid:0 用户是:shutdown 用户uid:6 用户gid:0 用户是:halt 用户uid:7 用户gid:0 用户是:mail 用户uid:8 用户gid:12 用户是:operator 用户uid:11 用户gid:0
2、变量
内建变量: FS: input field seperator,默认为空白字符 -F‘:‘ FS=‘:‘ OFS: output field seperator,默认为空白字符 RS: input record seperator,输入时换行符 ORS: output record seperator,输出时换行符 NF: number of field,字段设置: {print NF},{print $NF} NR: number of record: 行数 FNR: 各文件分别计数:行数; FILENAME: 当前文件名 ARGC: 命令行参数的个数 ARGV: 数组,保存的是命令行所给定的各参数 自定义变量: 1)-v var=value 2)在program中直接定义
案例1:打印用户名和对应的shell
[ ~]# awk -F":" ‘{print $1,$7}‘ passwd [ ~]# awk -v FS=":" ‘{print $1,$NF}‘ passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin operator /sbin/nologin
案例2:通过OFS定义输出分隔符
[ ~]# awk -F‘:‘ -v OFS="‘s shell is " ‘{print $1,$NF}‘ passwd root‘s shell is /bin/bash bin‘s shell is /sbin/nologin daemon‘s shell is /sbin/nologin adm‘s shell is /sbin/nologin lp‘s shell is /sbin/nologin sync‘s shell is /bin/sync shutdown‘s shell is /sbin/shutdown halt‘s shell is /sbin/halt mail‘s shell is /sbin/nologin operator‘s shell is /sbin/nologin
案例3:打印文件行号
[ ~]# awk ‘{print NR,$0}‘ passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
案例4:自定义变量
[ ~]# awk -v name=xiaoming ‘{print name,$0}‘ passwd xiaoming root:x:0:0:root:/root:/bin/bash xiaoming bin:x:1:1:bin:/bin:/sbin/nologin xiaoming daemon:x:2:2:daemon:/sbin:/sbin/nologin xiaoming adm:x:3:4:adm:/var/adm:/sbin/nologin xiaoming lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin xiaoming sync:x:5:0:sync:/sbin:/bin/sync xiaoming shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown xiaoming halt:x:7:0:halt:/sbin:/sbin/halt xiaoming mail:x:8:12:mail:/var/spool/mail:/sbin/nologin xiaoming operator:x:11:0:operator:/root:/sbin/nologin
3、printf
格式化输出:printf FORMAT,item1,item2 print item1,item2 print $1,$2 printf "%s,%s",$1,$2 1)FORMAT必须要 2)不会自动换行,需要给出换行控制符,\n 3)FORMAT中需要分别为后面的每个item指定一个格式化符号 格式符: %c:显示字符的ASCII码 %d,%i:显示十进制整数 %e,%E:显示科学计数法数值 %f:显示浮点数 %g,%G:以科学计数法或浮点形式显示数值 %s:显示字符串 %u:无符号整数 %%:显示%自身 修饰符 m[.n]:m控制显示的宽度,n表示小数点后的精度 %3.1f -:左对齐 +:显示数值的符号
案例1:显示多次字符串并左对齐
[ ~]# awk -F‘:‘ ‘{printf "uid:%10-s\tgid:%s\n",$1,$3}‘ passwd uid:root gid:0 uid:bin gid:1 uid:daemon gid:2 uid:adm gid:3 uid:lp gid:4 uid:sync gid:5 uid:shutdown gid:6 uid:halt gid:7 uid:mail gid:8 uid:operator gid:11 [ ~]# echo ‘123 456‘ | awk ‘{printf "%s%s\n",$1,$2}‘ | sed -r ‘s#(1)(2)(3)(4)(5)(6)#\6\5\4\3\2\1#‘ 654321 [ ~]# echo ‘1 2 3 4 5 6‘ | awk ‘{print $6$5$4$3$2$1}‘ 654321
4、操作符
算数操作符 x+y,x-y,x*y,x^y,x%y -x +x 字符串操作符:没有符号的操作符,字符串连接 赋值操作符: =,+=,-=,*=,/+,%=,^= ++,-- 比较操作符 >,>=,<,<=,!=,== 模式匹配符号: ~:匹配 !~:不匹配 逻辑操作符: && || ! 函数调用: function_name(argu1,argu2,...) 条件表达式 selector?if-true-expression:if-false-expression
案例1:四则运算
[ ~]# echo | awk ‘{printf "%.2f\n",2/3}‘ 0.67 [ ~]# echo | awk ‘{printf "%.2f\n",2+3}‘ 5.00 [ ~]# echo | awk ‘{printf "%.2f\n",3-2}‘ 1.00 [ ~]# echo | awk ‘{printf "%.2f\n",3*2}‘ 6.00 [ ~]# echo | awk ‘{printf "%.2f\n",3%2}‘ 1.00 [ ~]# echo | awk ‘{printf "%.2f\n",3^2}‘ 9.00
案例2:比较运算符
//打印出系统用户的信息 [ ~]# awk -F‘:‘ ‘$3<1000‘ passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin [ ~]# awk -F‘:‘ ‘$3>=1000{print $1}‘ passwd oldboy oldgirl
案例3:逻辑运算符
//打印非root用户的系统用户信息 [ ~]# awk -F‘:‘ ‘$1!="root" && $3<1000‘ passwd [ ~]# awk -F‘:‘ ‘$1!~"root" && $3<1000‘ passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin //打印管理员和非系统用户信息 [ ~]# awk -F‘:‘ ‘$1~"root" || $3>=1000‘ passwd root:x:0:0:root:/root:/bin/bash oldboy:x:1002:0:root:/root:/bin/bash oldgirl:x:1003:0:root:/root:/bin/bash #打印根分区已使用超过2G,打印根分区已占用空间 [ ~]# df | awk ‘/\/$/ && $3>2000000 {print $4} ‘ 15121276
案例4:模式匹配
//打印bash结尾的用户名和登录shell信息 解法一: [ ~]# awk -F‘:‘ ‘/bash$/{print $1,$NF}‘ passwd root /bin/bash oldboy /bin/bash oldgirl /bin/bash 解法二: [ ~]# awk -F‘:‘ ‘$NF~/bash/{print $1,$NF}‘ passwd root /bin/bash oldboy /bin/bash oldgirl /bin/bash 解法三: [ ~]# awk -F‘:‘ ‘$NF=="/bin/bash" {print $1,$NF}‘ passwd root /bin/bash oldboy /bin/bash oldgirl /bin/bash
案例5:条件表达式
//打印用户名,并显示uid大于等于1000的普通用户,小于1000的是系统用户 [ ~]# awk -F‘:‘ ‘{$3<1000?usertype="SysUser":usertype="ComUser";printf "%10-s\t%s\n",$1,usertype}‘ passwd root SysUser bin SysUser daemon SysUser adm SysUser lp SysUser sync SysUser shutdown SysUser halt SysUser mail SysUser operator SysUser oldboy ComUser oldgirl ComUser
5、PATTERN
1)empty:空模式 2)/regular expression/:仅处理能够被匹配的行 3)关系表达式:结果为真才会被处理 真:结果非0 4)行范围 /pat1/,/pat2/ 不支持直接给出数字的格式 5)BEGIN/END模式 BEGIN{}:仅在开始处理文件中的文本之前执行一次 {} END{}:仅在文本处理之后执行一次 行处理前 行处理 行处理后
[ ~]# awk -F‘:‘ ‘/^r/,/^o/{print $1}‘ passwd root bin daemon adm lp sync shutdown halt mail operator [ ~]# awk -F‘:‘ ‘NR>=2&&NR<=10{print $1}‘ passwd bin daemon adm lp sync shutdown halt mail operator
[ ~]# awk -F‘:‘ ‘BEGIN{printf "username\tuid\tgid\tdesc\t\thome\t\tshell\n-------------------\n"}{printf "%10-s\t%4-s\t%s\t%10-s\t%15-s\t%s\n",$1,$3,$4,$5,$6,$7}END{print "--------------------"}‘ passwd username uid gid desc home shell ------------------- root 0 0 root /root /bin/bash bin 1 1 bin /bin /sbin/nologin daemon 2 2 daemon /sbin /sbin/nologin adm 3 4 adm /var/adm /sbin/nologin lp 4 7 lp /var/spool/lpd /sbin/nologin sync 5 0 sync /sbin /bin/sync shutdown 6 0 shutdown /sbin /sbin/shutdown halt 7 0 halt /sbin /sbin/halt mail 8 12 mail /var/spool/mail /sbin/nologin operator 11 0 operator /root /sbin/nologin oldboy 1002 0 root /root /bin/bash oldgirl 1003 0 root /root /bin/bash --------------------