Centos 6.6上awk命令的简单使用
分类:CentOS教程 阅读:66740 次
本文实验环境:vmware workstation 10 +Centos6.6 X86_64,文中命令请谨慎使用。
AWK是类UNIX操作系统中一款文本处理工具,同grep,sed并成为文本处理三剑客,使用上的侧重点为:生成格式化的文本报告,但awk有丰富的语法和灵活的变量,称其为一门独立的语言也不为过。下文仅仅是awk生成格式化文本报告功能的简单使用。
1.awk工作过程描述:
awk将被处理的文件,逐行读入;按照输入分隔符,对改行进行分割处理;分割后的行内容块的索引从1开始,索引0为整行内容;根据定义的处理方式对行内容进行匹配,若匹配条件,则以合适的格式打印相应的行数据块,若行数据不匹配相应条件,则不处理。
2.awk语法格式
对awk来说很难总结出一个完全适应任何场合的语法格式,就生成格式化文本报告功能来说可以勉强写为下面的:
$awk [option] '[PATTERN] { ACTION STATEMENT }' file
option:
经常用到的有2个:
-F PUNCT:指定输入分隔符。
-v VAL_NAME=VALUE:自定义变量值。下文有例子说明。
其它的部分,请根据下面的例子进行学习,文末尾再进行总结。
3.例子教学:
3.1)打印/etc/passwd文件中root用户条目的用户名,uid和shell。
先取出/etc/passwd文件中root用户的条目
可以看到关于root用户的条目处理时使用“:”为分隔符是个明智的选择,用户名在第一部分,uid在第三部分,shll在第七部分,所以可以使用awk这样来写,就满足题意:
上述awk表达式中,使用-F指定输入分隔符为“:”; ACTION为 print,就是打印的意思, STATEMENT是 $1,$3,$7
当然也可这样写:
总结一:ACTION: print
print:
格式:
print item1,item2,...
要点:
1)各item间使用逗号分隔,而输出时使用输出分隔符分隔,输出分隔符默认为空格。
2)输出的各item为字符串,数值和当前记录的字段($n),变量的值或awk的表达式,
数值会被隐式转换为字符进行输出。
3)print后面的item如果省略,相当于print $0;输出空白 相当于print " "
上述2种awk表达方式可以完成题目的要求,但是输入的内容不是很美观,可以使用printf 代替print 来打印输出格式:
"USERNAME:%-s\nUID:%-d\nSHELL:%-s\n" 是格式符,因后边有3个部分要打印,故这里给出了3个格式符,USERNAME:%-s\n是针对第一个item即题目中的要打印的用户名,UID:%-d\n是针对第二个item即题目中的要打印的UID,SHELL:%-s\n针对的是第三个item即用户的shell。并且每个格式符中明确指定了换行符\n
虽然好看了,但是awk表达式也复杂起来,下面就总结下ACTION中printf的使用:
总结二:ACTION:printf:
格式:
printf format,item1,item2,...
要点:
1)printf中format称为格式符,是必须的,需明确给出
2)不会自动换行,需显示指定换行符\n
3)format中需要分别为后面每一个item指定一个格式符
格式符:都以%开头,后跟一个字符
%c:显示字符ASCII码,其实显示字符本身
%d %i:显示十进制格式的整数
%e %E:科学计数法显示数值
%f:显示浮点数
%g %G:以科学计数法格式或浮点数格式显示数值
%s:显示字符串
%u:显示无符号整数
%%:显示%自身
格式的修饰符:
#[.#]:第一个#为数字,显示宽度,后边.#在表达浮点数时表示精度
-:左对齐,默认右对齐
+:显示数值的符号, 正负数
3.2)使用"#"为连接符,显示系统上root用户的名称,uid和shell的设定
总结三:awk变量:FS为行输入分隔符,OFS为行输出分隔符,使用-v val_name=value来定义,-F PUNCT也是指定输入分隔符的,二者默认为空格。
3.3)打印/etc/passwd文件中用户名为一行
因awk是逐行对文件进行处理的,故/etc/passwd文件中每行的$1就是用户名,但是对输出换行符不进行指定的话,打印出来是这个样子:
因此需要指定输出换行符,这样才可将/etc/passwd文件中用户名打印为一行
总结三:awk变量:RS为awk输入换行符,ORS为输出换行符,使用-v val_name=value来定义
3.4)显示/etc/passwd中第一行有几个字段,并打印最后那个字段
总结三:awk变量:NF为当前行可被分割的成几个字段,$NF为被分割后最后那个字段,需指明行分隔符,默认为空格。
3.5)打印显示/etc/issue和/etc/sysconfig/network的行和行号,仔细观察下面三段显示的不同
总结三:awk变量:一行命令中同时处理多个文件时,NR:后边要处理的文件的行进行统一计数,显示当前行的行号。FNR:后边每个要处理的文件的行数单独计数时,显示当前行的行号。FILENAME:当前被处理的文件的文件名。
3.6)
(1)打印显示/etc/passwd文件中普通用户的信息
在centos6.6上系统中的匹配用户的uid从500开始的,故这里只需打印/etc/passwd文件中uid列大于等于500的用户行即可
这里用到可行模式匹配,即awk语法格式中的pattern的定义。
总结四:PATTERN:
关系表达式,即上例中的'$3>=500
涉及到比较操作符: >,>=,< ,<=,==,!=
(2)使用ifconfig eth1显示eth1网卡的配置信息,抓取ip地址所在的行
因IP地址所在的行在第二行,故借助NR可以抓取出来。
3.7)显示/etc/passwd文件中root用户行信息
因在/etc/passwd文件每一行开头的都是用户名,故抓取root开头且为独立单词的行即可,正则表达式为^root\>
总结四:PATTERN:
/regular expression/:仅处理能被/regular expression/匹配的行
上述例子中root若不加词尾锚钉,会出现下列现象:
3.8)显示/etc/passwd文件中root开头的行至shutdown开头的行之间的内容
总结四:PATTERN:
line rangs:行范围,类似于sed 或vim 中的定界符,startline,endline
3.9)打印系统上shell为bash的用户,开始和结束要有明确提示:
总结四:PATTERN:
BEGIN:同要处理的文件内容没关系,只是在所有awk动作之前执行一个动作
END:在awk所有的动作结束后,执行的动作
3.10)显示系统中的用户uid在0与100之间的用户
因用户的UID在/etc/passwd文件中第3部分,因此只要对/etc/passwd文件使用":"为输入行分隔符,抓取第三部分进行条件过滤即可实现
总结五:awk中的控制语句if;
格式:
if(condition){statement1;statement2;...}[else {statement1;statement2;...}]
当 statement只有一个时,{}可以被省略
单分支if语句时 {}可省略
上面的例子中if语句相当于2个if语句的嵌套,若写成bash脚本格式如下:
if [ $3 -gt 0 ];then
if [ $3 -lt 100 ];then
echo .....
fi
fi
awk中是不是不用写关闭符很爽,不用写bash脚本那样死板的格式很爽,那就去玩玩python吧,python的脚本写着同样很爽,至少比bash 爽。
3.11)显示/etc/inittab文件第一句中每个字段的长度
总结五:awk中的控制语句:while
格式:
while(condition){statment1;statment2;...}
条件为真时循环,直到为假时退出;
通常用于在当前行的各字段间进行循环。
在上面的awk语句中定义了变量i,NF为awk内置变量表示当前行可被分割成的字段数,当变量i<=NF为真时,while循环启动,显示$i为index的字段,length($i)为字段的长度,让后用i++自加,指导i<=NF为假时,停止while循环,停止打印。
上面的例子使用另外一种格式来实现:
总结五:awk中的控制语句:for
格式:
for:
for(expr1;expr2;expr3) statement
expr1:变量初始值
expr2:条件
expr3:变量变化
3.12)打印/etc/passwd中uid为奇数的用户条目
另外一种写法:
总结五:awk中的控制语句,中特殊关键字:
next:提前结束对本行的处理,而进入下一行的处理
break:跳出当前循环
continue:提前结束本轮循环,进入下一轮循环
在上面的例子中使用$3%2:$3对2取模,就是求余数,若余数为0,则被除数$3为偶数,若余数不为0则被除数$3为奇数。
3.13)统计当前OS的tcp连接状态和状态的个数
显示os的tcp连接状态:
可以看到左边第一列就是tcp的连接状态,但是第一行要去掉。
总结六:awk的数组:
格式:array_name[index-expression]
awk中的数组是关联数组,有的编程语言如python中会称关联数组为字典。
index-expression:可以使用任意字符串;
如果某数组元素不存在,在引用时,awk会自动创建该元素并将其初始化为空串
在数组中遍历每一个元素:使用 for(var in array){for body}
var会遍历array的每一个索引,print array[var]显示该索引代表的值
上面的例子中使用/^State/,这个正则表达式匹配#ss -tan的第一行,使用!/^State/ 表示对这个模式取反,即要处理不以State开头的行。定义了关联数组connect[],使用$1为数组的index值,处理每一行时,若connect[$1]存在则数字加1,若connect[$1]不存在则创建。awk动作结束后,使用for语句来处理,上例中i代表connect数组的index,connect[i]则为该index对应的值。
总结七:awk的内置函数处理字符串时使用:
字符串处理:
length([s]):返回指定字符串的长度
sub(r,s[,t]):以r所代表的模式来查找t字符串中的匹配,将其第一次出现替换同s所表示的字符串
#awk -F:'{sub(root,ROOT,$0)}' /etc/passwd
gsub(r,s[,t]):以r所代表的模式来查找t字符串中的匹配,将所有出现替换为s所表示的字符串
split(s,a[,r]):以r为分隔符切割字符串s,并将切割的结果保存至数组a中,
len=split(s,a[,r])为被切割后的段数
#netstat -tan|awk '/^tcp/{len=split($5,count,":");ip[count[len-1]]++}END{for(i in ip){print i,ip[i]}}'
<统计连接中,Foreign Address出现的次数>
substr(s,i[,n]):从s表示的字符串中取子串,从i开始,取n个字符
4 awk实际应用举例:
4.1)取出当前网卡eth1的ipv4地址:
eth1地址格式:
处理方式:
说明:-F '[ :]+' 指定输入行分隔符为 空格和':',+表示出现的次数至少1次,
inet addr : 192.168.100.2 。。。。
第一列 第二列 第三列 第四列 忽略
NR表示当前处理的行在文件中的位置行号。
若还是不明白,自己动手试试or画个圈圈诅咒自己的智商吧!
4.2)统计下面apache access日志中给出的ip地址和访问次数
处理方式:
这个就不用说了吧,只是awk管理数组和sort的联用,简单的有点可耻。
4.3)打印当前系统上,磁盘分区使用超过10%的分区的分区名,可使用空间和挂载点:
热门推荐
- centos rpm 安装
- CentOS6.5挂载超过16T的大容量存储空间
- CentOS7版本实现开机以图形界面启动
- CentOS修改系统的默认启动模式为命令号界面
- CentOS防火墙操作实例(启动、停止、开、闭端口)
- CentOS文件查看及编辑介绍
- CentOS常用网络配置及操作
- CentOS启动和停止服务详解
- centos增加网卡
- CentOS增加硬盘
- 关闭Centos写磁盘功能
- CentOS6.x下恢复误删文件
- CentOS 7使用nmcli配置网卡聚合链路
- CentOS 7 配置CDROM为本地YUM
- CentOS 7 自生成证书配置SSL WEB
- 阿里云ESC空间数据盘挂载
- CentOS用户账号管理
- CentOS下两台服务器直接进行文件传输
- Linux下多线程高速下载百度网盘资源的方法
- CentOS云主机下查看系统信息命令大全