创始人:Alfred Aho,Peter Weinberger, 和 Brian Kernighan
作用:处理文本文件,是一个强大的文本分析工具,它以列为划分计数的,$0表示所有列,$1表示第一列,$2表示第二列,以此类推。
语法:
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
options常用参数说明:
- -F 指定输入文件的分隔符
示例1,单个分隔符:
awk -F, '{print $1,$2}' test.log #表示使用逗号分割,展示第一列和第二列
示例2,多个分隔符:
$ awk -F '[_,]' '{print $1,$2,$3}' test.log #先使用下划线分割,然后对分割结果在使用逗号分隔
- -v 赋值一个用户定义的变量
示例:设置变量a为1
cat test.log | awk -v a=1 '{print $1,$1+a}'
输出结果:12 13,使用+做数值运算
cat test.log | awk -v a=1 '{print $1,$1"__"a}'
输出结果:12 12__1,使用双引号做拼接处理
- -f 从脚本文件中读取awk命令内容
脚本基本结构:
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号或双引号中,例如:
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename
工作原理:
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
- 第一步:执行BEGIN{ commands }语句块中的语句;
- 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
- 第三步:当读至输入流末尾时,执行END{ commands }语句块
!注意:在主体块部分没有关键字存在,BEGIN 和 END 是 AWK 的关键字,必须大写,脚本中可以没有开始块和结束块。
输出:
使用格式:print item1, item2.....
要点:
1、各项目之间使用逗号隔开,而输出时则以空白字符分隔显示;
2、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
3、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
- printf
printf format, item1, item2, ...
要点:
1、其与print命令的最大不同是,printf需要指定格式;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行,需要显式使用\n换行。
format格式的指示符都以%开头,后跟一个字符;如下:
%c:显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f:显示浮点数;
%g, %G:以科学计数法的格式或浮点数的格式显示数值;
%s:显示字符串;
%u:无符号整数;
%%:显示%自身;
- 输出重定向
1. 使用格式:
print items > output-file
print items >> output-file
print items | command
2. 特殊文件描述符:
/dev/stdin:标准输入
/dev/sdtout: 标准输出
/dev/stderr: 错误输出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;
例子:
awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd
模式:
- /正则表达式/:使用通配符的扩展集。
- 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。
- 模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
- BEGIN语句块、pattern语句块、END语句块。
操作:
操作由一个或多个命令、函数、表达式组成,之间有换行符或分号隔开,并位于大括号内,主要部分是:
- 变量或数组赋值
- 输出命令
- 内置函数
- 控制流语句
条件语句:
- IF语句:if (condition) action
- IF-ELSE语句:if (condition) action-1 else action-2
循环语句:
- for语句
for (initialisation; condition; increment/decrement)
action
initialisation:初始化局部变量;
condition:表达式,作为检查条件;
increment/decrement:变量的递增或递减。
示例:
$ awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'
输出结果:
1
2
3
4
5
- while语句:while (condition) action
while循环先检查条件是否为真,如果条件为真才执行动作,一直重复到条件为false时结束循环。
示例:
$ awk 'BEGIN {i = 1; while (i < 6) { print i; ++i } }'
输出结果:
1
2
3
4
5
结束循环:
- break:用于结束循环
- continue:结束本次循环,进入下次循环
- exit:结束脚本程序的执行
内建变量:
通常来说,分为两种类型的内置变量:
- 第一种是定义的变量可以改变, 比如字段分隔(FS)与记录分隔(RS)
- FS:设置输入字段的分隔符变量
读取并解析输入文件中的每一行,默认按照空格将行内容分隔为字段变量:$1,$2...等,可以是任意的字符串或者正则表达式。
语法:$ awk -F 'FS' 'commands' inputfilename 或 $ awk 'BEGIN{FS="FS";}'
示例:
第一步:新建文件etc_passwd.awk,内容如下所示
BEGIN{
FS=":";
print "Name\tUserID\tGroupID\tHomeDirectory";
}
{
print $1"\t"$3"\t"$4"\t"$6;
}
END {
print NR,"Records Processed";
}
第二步:使用awk的-f参数执行脚本文件etc_passwd.awk读取/etc/passwd下的数据内容
$ awk -f etc_passwd.awk /etc/passwd
输出结果(只取部分内容做示例):
_cmiodalassistants 262 262 /var/db/cmiodalassistants
_analyticsd 263 263 /var/db/analyticsd
_fpsd 265 265 /var/db/fpsd
_timed 266 266 /var/db/timed
_reportmemoryexception 269 269 /var/db/reportmemoryexception
108 Records Processed
- NF:一条记录的字段的数目
- 第二种是可以用来数据处理或者数据总结,比如记录数(NR)与字段数目(NF)
- OFS:输出字段分隔符变量
按指定分隔符分隔字段内容做输出展示
示例:
$ awk -F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd
输出结果(只取部分内容做示例):
71=71
72=72
73=73
74=74
75=75
76=76
- RS:记录分隔符
- ORS:输出记录分隔符变量
- NR:记录数变量
- FILENAME:当前输入文件的文件名称
- FNR:当前输入文件的记录数目
数组:
语法格式:array_name[index]=value
说明:
array_name:数组的名称
index:数组索引
value:数组中元素所赋予的值