cat emp.data
Beth 4.00 0
Dan 3.75 0kathy 4.00 10
Mark 5.00 20Mary 5.50 22S
usie 4.25 18
awk '$3>0 {print $1,$2*$3}' emp.data
kathy 40
Mark 100
Mary 121
Susie 76.5
awk '{print NF,$1,$NF}' emp.data
3 Beth 0
3 Dan 0
3 kathy 10
3 Mark 20
3 Mary 22
3 Susie 18
awk '{print NR,$0}' emp.data
1 Beth 4.00 0
2 Dan 3.75 0
3 kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
awk '{print "total pay for",$1,"is",$2,$3}' emp.data
total pay for Beth is 4.00 0
total pay for Dan is 3.75 0
total pay for kathy is 4.00 10
total pay for Mark is 5.00 20
total pay for Mary is 5.50 22
total pay for Susie is 4.25 18
printf(format,value1,value2,value3…..)
format是字符串,包含要逐字打印的文本,穿插着format之后的每个值该如何打印的规格(specification),一个规格是一个%符,后面跟着一些字符,用来控制一个value的格式。
其中第一个规格来说明打印value1,第二个规格用来说明打印第二个value2,以此类推
%s,以字符串的方式打印
%.2f,以数字的方式打印,并保留小数点后两位
%-8s,以字符串形式在8个字符串宽度的字段中左对齐输出
%6.2f,以数字形式,保留小数点后两位,在6个字符宽度的字段中输出
例如:
1、{printf(“total pay for %s is $%.2f\n”, $1,$2*$3)}
2、{printf(“%-8s $%6.2f\n”,$1,$2*$3)}
例如:假设要打印每位员工的所有数据,包括他或她的薪酬,并以薪酬递增的方式进行排序输出,最简单的方式是使用awk将每位员工的总薪酬置于其记录之前,然后利用一个排序程序来处理awk的输出。
使用sort排序:
awk ‘{printf(“%6.2f %s\n”, $2*$3,$0)}’ emp.data |sort
所谓选择就是根据条件进行筛选,符合条件的便被输出。
$2 >= 5 #第二个字段大于等于5的行会被打印出来
或者是通过简单的计算来选择。
$2$3 > 50 {printf(“$%.2f for %s\n”, $2$3,$1)} #通过计算打印出符合条件的行
通过文本内容选择。
$1 == “Susie” #打印第一个字段为Susie的行
或
/Susie/ #这个也可以匹配包含Susie的行
使用括号和逻辑操作符:与&&、或||、非!对模式进行组合。
$2 >= 4 || $3 >= 20 #打印第二列大于等于4或者第二列大于等于20的行
!($2 < 4 && $3 < 20) #注意是打印不满足括号里的内容的行
实际的数据中总是会存在错误的,在数据验证、检查数据的值是否合理以及格式是否正确的方面,awk可以发挥重要的作用
例如:
awk ‘NF !=3 {print $0,“number of fields is not equal to 3″}’ emp.data #会打印字段数不等于3的行
awk ‘$2 < 3.35 {print $0,“rate is below minion wage”}’ emp.data #打印字段数小于3.35的行
特殊模式BEGIN用于匹配第一个输入文件的第一行之前的位置,END则用于匹配处理过的最后一个文件的最后一行之后的位置
简而言之便是BEGIN用来输出第一个位置,END用来输出最后一个位置
awk 'BEGIN {print "Name Rate Hours";print ""} {print}' emp.data
Name Rate Hours
Beth 4.00 0
Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
awk 'BEGIN {print "Name Rate Hours";print ""} {print}END {print "chenfei"}' emp.data
Name Rate Hours
Beth 4.00 0Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
chenfei
例如:
使用一个变量emp来统计工作超过15个小时的员工的数目
[root@master text]# awk ‘$3 > 15 {emp=emp+1} END {print emp,“employees worked more than 15 hours”}’ emp.data
3 employees worked more than 15 hours
计算员工的数目,我们可以使用内置变量NR
# awk 'END {print NR,"employees"}' emp.data
6 employees
# awk '{pay = pay + $2*$3} END {print NR,"employees";print "total pay is",pay;print "avg pay is", pay/NR}' emp.data
6 employees
total pay is 337.5
avg pay is 56.25
示例文件:
# cat 1.log 220.194.106.164 – – [02/Aug/2019:12:40:04 +0800] “GET / HTTP/1.1” 200 23213 “-” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36” “88.99.137.13” 220.194.106.164 – – [02/Aug/2019:12:40:06 +0800] “GET /feed/ HTTP/1.0” 301 177 “-” “Mozilla/5.0 (X11; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0” “88.99.137.13” 138.118.226.183 – – [02/Aug/2019:12:47:08 +0800] “GET / HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36” “-” 103.43.18.91 – – [02/Aug/2019:13:01:46 +0800] “GET /.git/index HTTP/1.1” 301 177 “-” “git/1.7.9.5” “-” 103.43.18.91 – – [02/Aug/2019:13:01:46 +0800] “GET /.git/config HTTP/1.1” 301 177 “-” “git/1.7.9.5” “-” 218.68.91.198 – – [02/Aug/2019:13:19:00 +0800] “GET /2018-02-12/database/atlas%e5%8a%9f%e8%83%bd%e7%89%b9%e6%80%a7/ HTTP/1.1” 200 21265 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)” “207.46.13.35” 140.207.120.100 – – [02/Aug/2019:13:21:37 +0800] “GET /robots.txt HTTP/1.1” 301 177 “-” “Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)” “216.244.66.240” 223.166.151.243 – – [02/Aug/2019:13:21:42 +0800] “GET /robots.txt HTTP/1.1” 500 161 “-” “Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)” “216.244.66.240” 61.151.163.73 – – [02/Aug/2019:13:47:02 +0800] “GET /2019-03-05/python/python%e5%9f%ba%e7%a1%80-configparser%e6%a8%a1%e5%9d%97%e4%bd%bf%e7%94%a8/ HTTP/1.1” 200 18776 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)” “207.46.13.69” 223.166.151.243 – – [02/Aug/2019:14:07:08 +0800] “GET /robots.txt HTTP/1.1” 301 177 “-” “Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)” “216.244.66.240” 223.166.151.243 – – [02/Aug/2019:14:07:10 +0800] “GET /robots.txt HTTP/1.1” 500 161 “-” “Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)” “216.244.66.240” 103.43.18.91 – – [02/Aug/2019:14:19:01 +0800] “GET /tqpQx/ HTTP/1.1” 301 177 “-” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)” “-” 103.43.18.91 – – [02/Aug/2019:14:19:01 +0800] “GET /.svn/entries HTTP/1.0” 301 177 “-” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)” “-” 58.251.121.28 – – [02/Aug/2019:14:39:45 +0800] “GET /category/linux/page/3/ HTTP/1.1” 200 22944 “-” “Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)” “216.244.66.240” 103.4.117.26 – – [02/Aug/2019:14:46:08 +0800] “GET / HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36” “-” 180.163.22.108 – – [02/Aug/2019:14:49:48 +0800] “GET / HTTP/1.1” 200 24702 “-” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36” “119.57.68.210” 123.151.76.253 – – [02/Aug/2019:14:49:49 +0800] “GET /favicon.ico HTTP/1.1” 500 563 “https://www.devilf.cc/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36” “119.57.68.210” 223.166.151.243 – – [02/Aug/2019:14:55:01 +0800] “GET /2018-03-21/%E8%99%9A%E6%8B%9F%E5%8C%96/kubernetes%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/ HTTP/1.0” 301 0 “https://www.devilf.cc/2018-03-21/%E8%99%9A%E6%8B%9F%E5%8C%96/kubernetes%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/” “Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36” “5.188.45.160” 223.166.151.243 – – [02/Aug/2019:14:55:06 +0800] “GET /2018-03-21/%e5%ae%b9%e5%99%a8/kubernetes%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/ HTTP/1.0” 200 29212 “https://www.devilf.cc/2018-03-21/%e5%ae%b9%e5%99%a8/kubernetes%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/” “Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36” “5.188.45.160” 140.207.120.100 – – [02/Aug/2019:14:55:12 +0800] “GET /wp-admin/post-new.php HTTP/1.0” 302 0 “https://www.devilf.cc/wp-admin/post-new.php” “Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36” “5.188.45.160” 223.166.151.243 – – [02/Aug/2019:14:58:08 +0800] “GET /2018-04-04/python/python%e5%87%bd%e6%95%b0%e5%9f%ba%e7%a1%80/ HTTP/1.1” 200 20013 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)” “157.55.39.97” 58.250.143.116 – – [02/Aug/2019:15:00:21 +0800] “GET / HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1” “220.250.11.35” 58.251.121.28 – – [02/Aug/2019:15:00:22 +0800] “GET / HTTP/1.1” 200 23213 “http://www.devilf.cc/” “Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1” “220.250.11.35” 167.99.117.146 – – [02/Aug/2019:15:03:20 +0800] “HEAD / HTTP/1.1” 301 0 “https://www.netcraft.com/survey/” “Mozilla/4.0 (compatible; Netcraft Web Server Survey)” “-” 103.43.18.91 – – [02/Aug/2019:15:08:15 +0800] “GET /GUfMs/ HTTP/1.1” 301 177 “-” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)” “-” 103.43.18.91 – – [02/Aug/2019:15:08:15 +0800] “GET /.svn/entries HTTP/1.0” 301 177 “-” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)” “-” 140.207.120.100 – – [02/Aug/2019:15:30:07 +0800] “GET / HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36” “183.136.190.62” 220.194.106.164 – – [02/Aug/2019:15:45:28 +0800] “GET / HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36” “218.26.33.176” 220.194.106.164 – – [02/Aug/2019:15:49:34 +0800] “GET /wp-content/uploads/2018/09/img_5ba26dd318866.png HTTP/1.1” 301 177 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)” “123.125.71.27” 123.151.144.159 – – [02/Aug/2019:15:49:35 +0800] “GET /robots.txt HTTP/1.1” 301 177 “-” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36” “123.125.67.221” 218.68.91.198 – – [02/Aug/2019:15:49:35 +0800] “GET /robots.txt HTTP/1.1” 500 563 “-” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36” “123.125.67.160” 218.68.91.198 – – [02/Aug/2019:15:49:41 +0800] “GET /wp-content/uploads/2018/09/img_5ba26dd318866.png HTTP/1.1” 500 1 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)” “36.110.199.162” 140.207.120.100 – – [02/Aug/2019:15:49:45 +0800] “GET /wp-content/uploads/2018/09/img_5ba26dd318866.png HTTP/1.1” 500 1 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)” “36.110.199.162” 140.207.120.100 – – [02/Aug/2019:15:49:46 +0800] “GET /wp-content/uploads/2018/09/img_5ba26dd318866.png HTTP/1.1” 500 4096 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)” “36.110.199.162” 140.207.120.100 – – [02/Aug/2019:15:49:46 +0800] “GET /wp-content/uploads/2018/09/img_5ba26dd318866.png HTTP/1.1” 500 87421 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)” “36.110.199.162”
awk '{print $4}' 1.log | awk -F : '{sum[$3]+=1}END{for(i in sum)print i"\t"sum[i]}'
08 2
45 1
55 3
46 1
19 3
47 2
39 1
00 2
58 1
49 9
01 2
30 1
03 1
21 2
40 2
07 2
awk可以像大多数语言处理数字一样方便处理字符串,awk变量可以保存数字也可以保存字符串
[root@master text]# awk ‘$2 > maxrate {maxrate = $2;maxemp = $1} END {print “highest hourly rate:",maxrate,“for”,maxemp}’ emp.data
highest hourly rate: 5.50 for Mary
#这个会找出时薪最高的员工
maxrate保存着一个数值,而变量maxemp则是保存着一个字符串。
字符串链接:
可以合并老字符串来创建新字符串,这种操作成为连接。
[root@master text]# awk ‘{ names = names $1 " “} END { print names}’ emp.data
Beth Dan kathy Mark Mary Susie
通过将每个姓名和一个空格附加到变量names的前一个值,来将所有员工的姓名收集进单个字符串中。最后END动作打印出names的值
awk程序中,连接操作的表现形式是将字符串值一个接一个地写出来,对于每个输入行,程序的第一个语句先连接三个字符串:names的前一个值、当前行的第一个字段以及一个空格,然后将得到的字符串赋值给names,因此,读取所有的输入行之后,names就是个字符串,包含所有员工的姓名,每个姓名后面跟着一个空格,用与保存字符串的变量的默认初始值是空字符串(也就是说该字符串包含零个字符),因此这个程序中的names不需要显示初始化
打印最后一个输入行
[root@master text]# awk ‘{last = $0} END {print last}’ emp.data
Susie 4.25 18
内置函数:
内置函数可以用来计算有用的数值,平方根,对数,随机数,还有操作文本的函数,例如length,它用来计算一个字符串中的字符数量
awk ‘{print $1,length($1)}’ emp.data
Beth 4
Dan 3
kathy 5
Mark 4
Mary 4
Susie 5
行、单词、以及字符的计数
awk ‘{nc = nc + length($0) + 1;nw = nw + NF} END {print NR,“lines,",nw,“words,",nc,“character”}’ emp.data
6 lines, 18 words, 77 character
$0并不包含每个输入行的末尾的换行符,所以要另外加个1
控制语句:
if-else语句:
$2 > 6 { n = n + 1; pay = pay + $2 * $3 } END { if (n > 0) print n, “employees, total pay is”, pay, “average pay is”, pay/n else print “no employees are paid more than $6/hour” }
if-else 语句中,if 后的条件会被计算。如果为真,执行第一个 print 语句。否则,执行第二个 print 语句。注意我们可以使用一个逗号将一个长语句截断为多行来书写。
while语句
一个 while 语句有一个条件和一个执行体。条件为真时执行体中的语句会被重复执行。这个程序使用公式 value=amount(1+rate)years
来演示以特定的利率投资一定量的钱,其数值是如何随着年数增长的。
条件是 while 后括弧包围的表达式;循环体是条件后大括号包围的两个表达式。 printf 规格字符串中的 \t 代表制表符; ^ 是指数操作符。从 # 开始到行尾的文本是注释,会被awk忽略,但能帮助程序的读者理解程序做的事情。
你可以为这程序输入三个一组的数字,看看不一样的钱数、利率、以及年数会产生什么。例如,如下事务演示了1000美元,利率为6%与12%,5年的复利分别是如何增长的::
$ awk -f interest1 1000 .06 5 1060.00 1123.60 1191.02 1262.48 1338.23 1000 .12 5 1120.00 1254.40 1404.93 1573.52 1762.34
for语句
另一个语句, for ,将大多数循环都包含的初始化、测试、以及自增压缩成一行。如下是之前利息计算的 for 版本::
初始化 i = 1 只执行一次。接下来,测试条件 i <= $3 ;如果为真,则执行循环体的 printf 语句。循环体执行结束后执行自增 i = i + 1 ,接着由另一次条件测试开始下一个循环迭代。代码更加紧凑,并且由于循环体仅是一条语句,所以不需要大括号来包围它。
数组
awk为存储一组相关的值提供了数组。虽然数组给予了awk很强的能力,但在这里我们仅展示一个简单的例子。如下程序将按行逆序打印输入。第一个动作将输入行存为数组 line 的连续元素;即第一行放在 line[1] ,第二行放在 line[2] , 依次继续。 END 动作使用一个 while 语句从后往前打印数组中的输入行::
以 emp.data 为输入,输出为
Susie 4.25 18 Mary 5.50 22 Mark 5.00 20 Kathy 4.00 10 Dan 3.75 0 Beth 4.00 0
如下是使用 for 语句实现的相同示例::