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:02、变量
内建变量:
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/nologin3、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}‘
6543214、操作符
算数操作符 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 ComUser5、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
--------------------