什么是awk?
gawk - pattern scanning and processing language
查看帮助手册,可以发现它是模式扫描和处理语言。主要用途是用来处理文件的。
语法:
awk -f program-file file
awk program-text file ..
语法详解:
-f可以指定传入相应的awk脚本文件; 不指定-f时,就是直接写的编程文本。
由于awk是做扫描工作的,所以它必须要有输入。一般这个输入可以是文件,也可以是管道的输入,awk常与管道连接使用。
示例
grep '耗时' xxxx.log | awk '{match($0, /耗时:([0-9]+)/,result); print result[1]}' | awk '{ sum += $1; } END { print "sum = " sum; print "average = " sum/NR; print "nr=" NR }'
传入数据:
$1, $2表示第几个参数
$0: 表示一行所有的传入数据
NR: number of record 行数
NF: number of field 多少个参数
FNR: file number of record 当前文件的行数记录。如果多个文件,NR记录所有文件行数。
FS: Field seperator 列分割符 默认是" "(空白符)
RS: Rcoerd seperator 行分割符: 默认是"\n"
OFS: Output Field seperater 输出分隔符。默认是"\n"
awk -F : 用来指定多个数据间的分隔符。默认是" "
编程分区:
BEGIN{} {} END{}
三部分分别表示,处理第一行开始之前执行; 处理每一行时执行; 处理完之后执行。
数组:
awk的数组,是一种关联数组(Associative Arrays 也称哈希表,或者map),下标可以是数字和字符串。因无需对数组名和元素提前声明,也无需指定元素个数 ,所以awk的数组使用非常灵活。
以下,由于awk的数组其实是map,那么,其实它的key值即可以是数字,也可以是字符串。还可以是负数,也不在乎连续性。
未赋值的key:
对应的值为空
1 一维数组
a) 数字下标
array[1]="it"
array[2]="homer"
array[3]="sunboy"
b) 字符下标
array["first"]="yang"
array["second"]="gang"
array["third"]="sunboy"
获取数组长度:
len=length(array);
多维数组:
awk不支持多维数据,可以使用"0,0"这样的值为key来模拟。
数组排序
1、asort方法:
asort只对值进行了排序,因此丢掉原先键值。
srcarrlen=asort[srcarr,dscarr] 默认返回值是:原数组长度,传入参数dscarr则将排序后数组赋值给dscarr.
$ awk 'BEGIN{ a[100]=100; a[2]=224; a[3]=34; slen=asort(a,tA); for(i=1;i<=slen;i++) {print i,tA[i];} }' 1 34 2 100 3 224
2、asorti 与asort用法相同,不同的是,它对key进行排序
$ awk 'BEGIN{ a["d"]=100; a["a"]=224; a["c"]=34; slen=asorti(a,tA); for(i=1;i<=slen;i++) {print i,tA[i],a[tA[i]];} }' 1 a 224 2 c 34 3 d 100
循环:
两种写法
#!/bin/bash
awk 'BEGIN{
for(i=1; i<=5; i++){
array[i] = i*2 - 1;
}
for(i in array){
print i" = " array[i];
}
}'
变量
awk中,变量无需声明。
如果为数,则默认为0
ll | awk '{a += 1; print a}' #输出: 1 2
awk中,不支持字符串+=的操作。
条件判断
语法:
跟其他语言的很像。表达式还是 > >=这些
if (表达式 ) {
语句;语句;...
} else {
语句;语句;...
}
常用输出方法
print 直接输出 默认换行 print $1" "$2 #对于要输出的其他字符串,需要使用双引号引起来
printf 格式输出,跟C++里面的差不多。
匹配函数match
格式:
match(string, regexp, array)
string: 源数据
regexp: 正则匹配,一分会在此分组。匹配最左,最长的substring, 返回index
array: 存储数据.0 代码匹配的所有数据, array[1] 代表第1个()中的内容。
主要用途:
我主要用于日志统计中的耗时
用法示例:
grep '耗时' xxxx.log | awk '{match($0, /耗时:([0-9]+)/,result); print result[1]}' | awk '{ sum += $1; } END { print "sum = " sum; print "average = " sum/NR; print "nr=" NR }'
awk脚本文件
awk -f xxx.awk
文件名:
xxx.awk 这里的后缀不是必须的。
以下是文件内容: 脚本文件为平时命令行中的''中的内容
BEGIN { printf "%s\n","Writing my first awk executable script!" }
awk 执行linux命令行
awk提供了两种方式来调用linux shell。
第一种是使用system("cmd")函数。我个人比较推荐使用这种方式。
第二种是使用print(cmd, args)函数。这样也可以达到执行shell命令的条件。
echo 123 | awk '{print(echo,1234)}' #最终输出为1234 echo 123 | awk '{system("echo 1234")}' #最终输出为1234
awk正则匹配的方式
其中 //中的是正则表达式。 /正则表达式/
在if中用正则表达式。 if( xx ~ /正则/) ~ 后面跟正则,可以正常的使用正则表达式。
awk '/lu/ {print $0}' < tt.txt awk '{if( $0 ~ /lu/ )print $0}' < tt.txt
参考文档:
别人写得比较好的