Linux文本处理三剑客:
1.grep,egrep:文本过滤
2.sed:行编辑器
3.awk报表生成器,格式化文本输出
linux中把awk链接到了gawk,使用的是GNU项目中的awk。
AWK工作模式,读取一行文本,利用内置或者指定的字段分隔符去分隔这行文本,把每字段赋值给内置的位置变量,如第一段$1,第二段$2……整行可以赋值$0然后引用。
awk是一种编程语言,用于在linux下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。
2.awk基本语法和选项2.1基本语法
gawk[options]’program’file file……
program:PATTERN(模式){ACTION(处理动作)STATEMENT(输出字段)},由语句组成,语句之间由分号分隔
2.2awk选项
-F[]:指定输入字段的分隔符
-v var=val:变量赋值
awk -F: '{print $1,$3}' /etc/passwd awk -v FS=":" '{print $1,$3}' /etc/passwd
2.3awk的输出命令
print item….
注意:
1.item之间用逗号分隔,而输出时使用输出分隔符
2.输出各item可以是字符串或者数值,也可以当前文本的字段($n),变量或者awk的表达式;数值会被隐式转换成字符输出。
3.print后面的item如果省略,输出整行信息
2.4printf命令
2.4.1.printf format item……
注意:
1.format是必须的
2.不会自动换行,需指定
3.format要给每个item指定一个格式符
2.4.2.格式符以%开头,后面跟一个字符
%c:显示字符的ASCII码
%d,%i:显示十进制整数
%e,%E:科学计数法显示数值
%f:显示浮点数
%g,%G:以科学计数法格式或浮点数格式显示数值
%s:字符串
%u:无字符的整数
%%:显示%自身
2.4.3修饰符
#[.#]第一个数字显示宽度如:%5s 第二个数字显示精度如 :%5.4s
-:左对齐
+:显示数值符号
2.4.4操作符
算数操作符
+ – * / ^ %:加 减 乘 除 次方 取余
字符串操作符:字符串连接
赋值操作符:
=,+= ,–=
比较操作符:> >= < <= == !=
模式匹配符:~ !~
逻辑操作符:&& ||
条件表达式:selector?if-true-expression:if-false-expression
函数调用:
functiong_name()
2.5.PATTERN
1)/regular expression/:仅处理能被/regular expression/匹配到的行
2)relational expression:关系表达式
3)line ranges:行范围,类似sed或者vim的地址定界
4)BEGIN/END:在运行awk运行程序之前运行一次BEGIN;在运行awk完之后执行一次END
5)empty:空模式,匹配任意行
2.6常用的action
3.awk的变量1)表达式
2)控制语句
a)if-else语法,通常对行或者行中的字段做条件判断
if(条件)statement[else statement]
if(条件){statement;} [else {statement;}]花括号内能有多个语句,用分号分隔。
b)while循环,通常在当前行各字段间循环
while(条件)statement
while(条件){statement;}
c)do-while循环
do statement while (condition)
d)for循环
for(expr1:….) {statement;}
e)gawk有对switch语句的支持
f)break,continue
break退出当前循环
continue提前结束本轮循环,进入下轮循环
g)next提前结束对本行的处理,进入下行
3)复合表达式
4)输入语句
5)输出语句
3.1内置变量
FS:字段分隔符,默认是空格
RS:记录分隔符,默认为换行符
OFS:输出字段分隔符,默认是空格
ORS:输出记录分隔符,默认换行符
NF:当前记录的字段数
NR:当前行数,所有文件一起计数
FNR:每个文件的行数
FILENAME:当前文件名
ARGC:命令行的参数个数
ARGV:命令行的数组,保存awk和他的参数
3.2自定义变量
-v var=val
变量区分大小写
1)可以在programe中定义
2)可以用-v 定义
4.awk的数组Array
关联数组:array[index-expression]
index-expression:
可以使用任意字符串;
如果某数组元素实现不存在,在引用时,awk会自动创建此元素并将其值初始化为空串:因此,若要判断数组是否存在某元素,要使用“index in array”进行;
例如:a[mon]=“Monday”
for循环在awk中有一个专用于遍历数组元素
语法:for(var in array){for-body}
var会遍历array的每一个索引,print array[var]
查询文档中字符串出现次数 awk '{for(i=1;i<=NF;i++) {count[$i]++}}END{for(n in count) {print n,count[n]}}' file 查询日志中ip出现次数 awk '{count[$1]++}END{for(n in count) {print n,count[n]}}' /var/log/httpd/access_log
5.函数
5.1内置函数
rand():返回0和1之间的随机数
length([s]):字符串的长度
$ awk '{ print length( "test" ) }'
gsub(r,s [,t])以r模式查找t代表的字符串,将其替换成s表示的字符串
$ awk '{ gsub(/test/, "mytest"); print }' testfile 在整个文档中匹配test,匹配的都被替换成mytest
sub(r,s [,t])以r模式查找t代表的字符串,将其第一次匹配替换成s表示的字符串
$ awk '{ sub(/test/, "mytest"); print }' testfile 在整个记录中匹配,替换只发生在第一次匹配发生的时
split(s,a[,r]):以r为分隔符切割s字符串,结果保存在a代表的数组中,split函数的返回值是切割成的字段数。
例子,统计netstat -tan查询的访问状态中tcp协议访问的ip netstat -tan | awk '/^tcp/{num=split($5,ip,":");ipnum[ip[num-1]]++}END{for(n in ipnum);{print n,ipnum[n]}}' 先分段,把含IP的字段按冒号分隔,定义到ip数组中(num=split($5,ip,”:”)),把字段中ip地址取出来定义为ipnum数组并且重复一次加1(ipnum[ip[num-1]]++)最后遍 数组,统计数值。
substr(s,i[,n]):从s字符串取子串,从i开始,取n个字符
$ awk '{ print substr( "hello world", 7,11 ) }' 截取了world字符
systime:取时间戳;
and(v1,v2)
5.2自定义函数
function f-name (p,q)
{
}