目录
AWK是什么
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。有多种版本:New awk(nawk),GNU awk( gawk)等。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk是由模式和操作组成。模式包括正则表达式、关系表达式、模式匹配表达式和(BEGIN语句块、pattern语句块、END语句块)。操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内
AWK基本结构
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file
由BEGIN语句块、用于匹配信息的语句块、END语句块三部分组成。
这三个部分是可选的。任意一个部分都可以不出现在脚本中。
执行顺序为:
-
第一步:执行
BEGIN{ commands }
语句块中的语句; -
第二步:从文件或标准输入(stdin)读取一行,然后执行
pattern{ commands }
语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。 -
第三步:当读至输入流末尾时,执行
END{ commands }
语句块。
a.txt的文本实例
a.txt内容如下
1 2 3
4 5 6 19
7 8 9 29 35
2 3 5 6 7
我想输出每行的第一列数据。注:print表示输出,$1表示第一列
awk '{print $1}' a.txt
结果
1
4
7
2
AWK内置变量
[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
$0 这个变量包含执行过程中当前行的文本内容。
[N] ARGC 命令行参数的数目。
[G] ARGIND 命令行中当前文件的位置(从0开始算)。
[N] ARGV 包含命令行参数的数组。
[G] CONVFMT 数字转换格式(默认值为%.6g)。
[P] ENVIRON 环境变量关联数组。
[N] ERRNO 最后一个系统错误的描述。
[G] FIELDWIDTHS 字段宽度列表(用空格键分隔)。
[A] FILENAME 当前输入文件的名。
[P] FNR 同NR,但相对于当前文件。
[A] FS 字段分隔符(默认是任何空格)。
[G] IGNORECASE 如果为真,则进行忽略大小写的匹配。
[A] NF 表示字段数,在执行过程中对应于当前的字段数。
[A] NR 表示记录数,在执行过程中对应于当前的行号。
[A] OFMT 数字的输出格式(默认值是%.6g)。
[A] OFS 输出字段分隔符(默认值是一个空格)。
[A] ORS 输出记录分隔符(默认值是一个换行符)。
[A] RS 记录分隔符(默认是一个换行符)。
[N] RSTART 由match函数所匹配的字符串的第一个位置。
[N] RLENGTH 由match函数所匹配的字符串的长度。
[N] SUBSEP 数组下标分隔符(默认值是34)。
a.txt的文本实例
参照上边a.txt文本。参照内置变量,我想计算每行有多少数据
awk '{print NF}' a.txt
结果
3
4
5
5
我想打印第i行第i列的字段,比如第1行第1列,第2行第2列……
awk '{print $NR}' a.txt
结果
1
5
9
6
我想打印全文本,并且给每行打印行号
awk '{print NR,$0}' a.txt
结果
1 1 2 3
2 4 5 6 19
3 7 8 9 29 35
4 2 3 5 6 7
AWK自定义变量
自定义变量初始化为0。
传递外部变量方法案例:
[root@localhost ~]# LT=45
[root@localhost ~]# echo | awk '{print LT}' LT=$LT
45
[root@localhost ~]# LT=45
[root@localhost ~]# echo | awk -v L=$LT '{print L}'
45
a.txt的文本实例
我想计算每行第一列的数字和
awk '{a=a+$1} END{print a}' a.txt
结果
14
AWK内置函数
a.txt的文本实例
打印第一列的平方根
awk '{print sqrt($1)}' a.txt
结果
1
2
2.64575
1.41421
awk高级输出
print 语句可用于快速而简单的输出。若要严格按照你所想的格式化输出,则需要使用 printf 语句。
printf 不会自动产生空格或者新的行,必须是你自己来创建,所以不要忘了 \n 。
printf(format, value1, value2, ...)
a.txt的文本实例
[root@localhost ~]# awk '{ printf("%-8s $%6.2f\n", $1, $2 * $3) }' a.txt
1 $ 6.00
4 $ 30.00
7 $ 72.00
2 $ 15.00
解读:第一个规格 %-8s 将第一列以字符串形式在8个字符宽度的字段中左对齐输出。第二个规格 %6.2f 将第二列乘第三列以数字的形式,保留小数点后两位,在6个字符宽度的字段中输出。
排序输出
a.txt的文本实例
[root@localhost ~]# awk '{print $0}' a.txt | sort
1 2 3
2 3 5 6 7
4 5 6 19
7 8 9 29 35
条件选择输出
可以使用括号和逻辑操作符与 && , 或 || , 以及非 ! 对模式进行组合。
a.txt的文本实例
把第一列大于3的行输出
[root@localhost ~]# awk '$1>3 {print $0}' a.txt
4 5 6 19
7 8 9 29 35
把第一列大于3的行或第二列大于2的行输出
[root@localhost ~]# awk '$1>3||$2>2 {print $0}' a.txt
4 5 6 19
7 8 9 29 35
2 3 5 6 7
控制语句
if-else语句
while语句
for语句
a.txt的文本实例
把每行的数字和输出
[root@localhost ~]# awk '{a=0; for(i=1;i<NF+1;i=i+1){a=a+$i; if(i==NF){print a}}}' a.txt
6
34
88
23
把数据中大于5的数字相加求和
[root@localhost ~]# awk '{for(i=1;i<NF+1;i=i+1){if($i>5){a=a+$i}}} END{print a}' a.txt
126