四剑客awk

awk

使用awk取行
使用awk取列
使用awk取行+取列
通过awk进行初步计算与统计(eg,统计次数(wc -l),求和)

1.取行

1.1 取出/etc/passwd第3行 ⭐⭐⭐⭐⭐

NR awk中的内置变量.
NR Number of Record 记录号,行号
== 2个等号表示等于

[root@Kylin-V10-sp3 ~/test]# awk 'NR==3' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin

1.2 取出/etc/passwd 第3到10行⭐⭐⭐⭐⭐

awk 'NR>=3' /etc/passwd
== 等于
!= 不等于
>= 大于等于
> 大于
<= 小于等于
< 小于
awk 'NR>=3 && NR<=10' /etc/passwd
&& 并且,2个条件同时成立.

1.3 取出/etc/passwd中包含bash的行⭐⭐⭐⭐⭐

类似于egrep/grep/sed -n '//p'
awk过滤只需要使用//即可.

[root@Kylin-V10-sp3 ~/test]# grep 'bash' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@Kylin-V10-sp3 ~/test]# 
[root@Kylin-V10-sp3 ~/test]# sed -n '/bash/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@Kylin-V10-sp3 ~/test]# awk '/bash/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@Kylin-V10-sp3 ~/test]# 
# awk使用正则
[root@Kylin-V10-sp3 ~/test]# awk '/xk|root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@Kylin-V10-sp3 ~/test]# 

1.4 取出日志中指定时间段内的日志⭐⭐⭐⭐⭐

# 取出范围的日志的格式
seq 5 20 |sed -n '/从哪里来/ , /到哪里去/p'
seq 5 20 |awk '/从哪里来/ , /到哪里去/'

# 取出时间范围日志

# 检查是否有11号的15:00的日志
[root@Kylin-V10-sp3 /opt/packages]# grep '11 15:00' secure-20161219 |wc -l
113
[root@Kylin-V10-sp3 /opt/packages]# 
# 过滤出11号15:00到16:00的日志
[root@Kylin-V10-sp3 /opt/packages]# grep '11 16:00' secure-20161219 |wc -l
108
[root@Kylin-V10-sp3 /opt/packages]# sed -n '/11 15:00/ , /11 16:00/p' secure-20161219 |wc -l
6704
[root@Kylin-V10-sp3 /opt/packages]# sed -n '/11 15:00/ , /11 16:00/p' secure-20161219 >secue-15-16
[root@Kylin-V10-sp3 /opt/packages]# 
[root@Kylin-V10-sp3 /opt/packages]# ls
 secure-20161219    access.log           secue-15-16  secure-20161219.zip
[root@Kylin-V10-sp3 /opt/packages]# ls
 access.log  secue-15-16  secure-20161219  secure-20161219.zip
[root@Kylin-V10-sp3 /opt/packages]# 

# 过滤access.log与注意事项
# 过滤11:30分到11:31分日志
[root@Kylin-V10-sp3 /opt/packages]# sed -n '/22.Nov.2015:11:30:00/ , /22.Nov.2015:11:31:00/p' access.log |wc -l
3204
[root@Kylin-V10-sp3 /opt/packages]# sed -n '/22\/Nov\/2015:11:30:00/ , /22\/Nov\/2015:11:31:00/p' access.log |wc -l
3204

1.5 日志过滤专业版

[root@Kylin-V10-sp3 /opt/packages]# awk '$4>="[22\/Nov\/2015:11:11:13"' access.log | head -3
awk: cmd. line:1: warning: escape sequence `\/' treated as plain `/'
61.147.72.3 - - [22/Nov/2015:11:11:13 +0800] "GET /online/api/mc/productPromo/display/list/favors.json?salesChannelEnumId=109&language=zh_CN&eatingStyleEnumId=702&productStoreId=10300&estimatedDeliveryDate=20151122&_=1448161873472 HTTP/1.1" 200 14309 "http://www.papaonline.com.cn/online/oldboyonline/order/checkoutProducts.jsp" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36"
112.225.39.106 - - [22/Nov/2015:11:11:13 +0800] "POST /online/api/mc/sys/loginCrm.json HTTP/1.1" 200 715 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/account/accountMain.html" "Mozilla/5.0 (iPad; CPU OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/6.0 MQQBrowser/4.9.1 Mobile/12F69 Safari/7534.48.3"
114.91.12.166 - - [22/Nov/2015:11:11:13 +0800] "GET /mobile/theme/oldboy/home/images/20151111/04.png HTTP/1.1" 200 256028 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/home/index.html" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13B143 MicroMessenger/6.3.6 NetType/WIFI Language/zh_CN"
[root@Kylin-V10-sp3 /opt/packages]#  
[root@Kylin-V10-sp3 /opt/packages]# 
[root@Kylin-V10-sp3 /opt/packages]# awk '/04:10:00/,/04:11:00/' secure-20161219 | head -3
Dec 18 04:10:00 localhost sshd[29839]: Failed password for root from 218.87.109.151 port 63971 ssh2
Dec 18 04:10:01 localhost sshd[29839]: Failed password for root from 218.87.109.151 port 63971 ssh2
Dec 18 04:10:01 localhost sshd[29839]: Failed password for root from 218.87.109.151 port 63971 ssh2
[root@Kylin-V10-sp3 /opt/packages]# 

1.6 小结

  • 类似于sed命令.
  • NR内置变量用于表示行号.
  • Number of Record 记录号(行号)
  • 结合符号
==
!=
>=
<=
>
<
  • 未来过滤的需求(grep/egrep,sed,awk)

2.取列

2.1 取出ls -l /etc/hosts 文件第3列,最后一列⭐⭐⭐⭐⭐

NF awk内置变量.
NF Number of Fields 每一行有多少列,列数. $NF
column -t对前面的内容进行对齐.


[root@Kylin-V10-sp3 /opt/packages]# ll /etc/hosts |awk '{print $3,$5,$(NF-1),$NF}'
root 158 2020 /etc/hosts
[root@Kylin-V10-sp3 /opt/packages]# 
[root@Kylin-V10-sp3 /opt/packages]# ll | awk 'NR>1 {print $5,$NF}' |column -t
3765999   02-【awk练习文件】access-服务的访问日志-v3.zip
58817074  access.log
695947    secue-15-16
51053780  secure-20161219
2218287   secure-20161219.zip
[root@Kylin-V10-sp3 /opt/packages]#

2.2 取出/etc/passwd第1列第3列和最后一列⭐⭐⭐⭐⭐

awk中默认认为每一列的标记是空格,awk默认的分隔符是空格.
一些文件或命令的结果中,每一列不是以空格分割,这时候我们需要通过awk -F选
项指定新的分隔符.
awk -F可以指定分隔符.

[root@Kylin-V10-sp3 /opt/packages]# awk -F':' '{print $1,$3,$NF}' /etc/passwd | head -3
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
[root@Kylin-V10-sp3 /opt/packages]# 
[root@Kylin-V10-sp3 /opt/packages]# awk -F':' '{print $1,$3,$NF}' /etc/passwd |column -t | head -3
root              0      /bin/bash
bin               1      /sbin/nologin
daemon            2      /sbin/nologin
[root@Kylin-V10-sp3 /opt/packages]# 

2.3 取出ip a s eth0/ens33 中的ip地址 ⭐⭐⭐⭐⭐

ip a #ip address
ip a s eth0 #ip address show eth0显示指定网卡的信息
awk -F支持正则表达式,正则匹配到的内容将成为分隔符.

[root@Kylin-V10-sp3 /opt/packages]# ip a s ens33 |awk 'NR==3' |awk -F '[ /]+' '{print $3}'
10.0.0.36
[root@Kylin-V10-sp3 /opt/packages]# 
[root@Kylin-V10-sp3 /opt/packages]# ip a s ens33 |awk 'NR==3' |awk -F 'inet |/24' '{print $2}'
10.0.0.36
# 获取系统运行时间
[root@Kylin-V10-sp3 /opt/packages]# uptime |awk -F 'up |[0-9]+ user' '{print $2}'
19:55,  
[root@Kylin-V10-sp3 /opt/packages]# 

2.4 显示/etc/passwd每一行的内容与行号⭐⭐⭐⭐⭐

cat -n
NR表示行号.
print输出.
$0 整行,这一行的内容.

[root@Kylin-V10-sp3 ~]# awk '{print NR $0}' /etc/passwd | head -3
1root:x:0:0:root:/root:/bin/bash
2bin:x:1:1:bin:/bin:/sbin/nologin
3daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@Kylin-V10-sp3 ~]# 
温馨提示:
awk 'NR>=3' /etc/passwd
awk 'NR>=3{print $0}' /etc/passwd

2.5 取列小结

  • 取列格式awk '{print $xxx}'
  • 1 2 ..$NF取列
  • $(NF-1) 取倒数第2列.
  • awk -F选项指定分隔符,分隔符相当于是菜刀,每一列的结束标记.
  • awk -F选项支持正则
[root@Kylin-V10-sp3 ~]# stat /etc/hosts
  文件:“/etc/hosts”
  大小:158       	块:8          IO 块:4096   普通文件
设备:fd00h/64768d	Inode:134313582   硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2024-09-10 23:38:30.903737099 -0300
最近更改:2020-06-23 03:11:43.000000000 -0300
最近改动:2024-08-16 23:46:12.972479943 -0300
创建时间:-
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# stat /etc/hosts | awk 'NR==4' | awk -F '\\(|/' '{print $2}'
0644
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# stat /etc/hosts | sed -n '4p' | sed -r 's#^.*\(([0-9]{4})/.*$#\1#g'
0644
[root@Kylin-V10-sp3 ~]#

3.取行与取列

3.1 awk命令格式

awk -F: 'NR==1{print $1,$3,$NF}' /etc/passwd
awk 选项 '找谁{干啥}' /etc/passwd
找谁: 条件 用于让awk定位到某一行或几行.
干啥: 动作 满足上面条件后(找到这行后)如何处理这一行. print 取列.

动作部分可以省略,输出这一行的内容相当于
awk 'NR3' /etc/passwd #显示第3行内容.
awk 'NR
3{print $0}' /etc/passwd #与上面一致.

3.2 取出ip a s eth0/ens33 中的ip地址,合并成1个awk,使用1个管道⭐⭐⭐⭐⭐

[root@Kylin-V10-sp3 ~]# ip a s ens33 |awk 'NR==3' |awk -F '[ /]+' '{print $3}'
10.0.0.36
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# ip a s ens33 | awk -F '[ /]+' 'NR==3{print $3}'
10.0.0.36
[root@Kylin-V10-sp3 ~]# 

3.3 小结

  • 核心使用awk可以进行取行+取列操作.
  • 对文件或命令做到指哪打哪

4.计算与统计

  • 使用awk进行求和.
  • 使用awk进行计算的百分数(一般会结合取行取列).

4.1 通过awk实现wc -l效果.

计数,统计次数.
未来统计次数的需求,推荐使用wc -l

awk '{统计与计算} END{awk读取文件后,才会执行,一般用于输出最后的结果}'
i=i+1
END{awk读取文件后,才会执行,一般用于输出最后的结果}
i=666
i=i+1 === i++
i+1执行,结果写入到i
当前的i 执行i=i+1 之后的i
第1次运行 0 i=0+1 1
第2次运行 1 i=1+1 2
第3次运行 2 i=2+1 3
[root@Kylin-V10-sp3 ~]# awk '{i++} END {print i}' /etc/services 
11473
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# wc -l /etc/services 
11473 /etc/services
[root@Kylin-V10-sp3 ~]#

4.2 统计seq 10结果的总和 ⭐⭐⭐⭐⭐

# END{}一般用于数据分散在不同的行.需要使用END{}
[root@Kylin-V10-sp3 ~]# seq 10 | awk '{i+=$1} END{print i}'
55
[root@Kylin-V10-sp3 ~]# 
# access.log是访问日志,日志的第10列是用户访问的资源的大小,对大小求和,形式以MB或GB形式展示
# 第10列默认是字节.
[root@Kylin-V10-sp3 ~]# awk '{i+=$10} END {print i/1024^3"GB"}' /opt/packages/access.log 
2.30828GB
[root@Kylin-V10-sp3 ~]# 

4.3 统计free结果中内存空闲率 ⭐⭐⭐⭐⭐

[root@Kylin-V10-sp3 ~]# free 
              total        used        free      shared  buff/cache   available
Mem:         970908      307264      241952       15568      421692      481392
Swap:       2207740        5644     2202096
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# free | awk 'NR==2 {print $7/$2*100"%"}'
49.8692%

4.4 小结

记忆awk两个常用公式. i++ (i=i+1) wc -l i+=$xxx (i=i+ $xxx)
使用awk进行求和.
使用awk进行计算的百分数(一般会结合取行取列)

5.一些补充

5.1 取出UID大于等于0小于等于1000的行数量.⭐⭐⭐⭐⭐

点击查看代码
[root@Kylin-V10-sp3 ~]# awk -F : '$3>=0 && $3<=1000 {i++} END {print i} '  /etc/passwd 
38

# 取出系统磁盘使用率大于10%的行

# 查看数据结构
[root@Kylin-V10-sp3 ~]# df -h
文件系统                 容量  已用  可用 已用% 挂载点
devtmpfs                 459M     0  459M    0% /dev
tmpfs                    475M     0  475M    0% /dev/shm
tmpfs                    475M   19M  456M    4% /run
tmpfs                    475M     0  475M    0% /sys/fs/cgroup
/dev/mapper/klas-root     66G  4.2G   61G    7% /
tmpfs                    475M     0  475M    0% /tmp
/dev/mapper/klas-backup   32G  270M   32G    1% /backup
/dev/sda1               1014M  151M  864M   15% /boot
tmpfs                     95M     0   95M    0% /run/user/0
[root@Kylin-V10-sp3 ~]# 
# 猜测并验证分割结果
[root@Kylin-V10-sp3 ~]# df -h | awk -F '[ %]+' 'NR>1 {print $5}'
0
0
4
0
7
0
1
15
0
# 找出符合数据的行
[root@Kylin-V10-sp3 ~]# df -h | awk -F '[ %]+' 'NR>1 && $5>10 {print $5}'
15
# 符合数据的行一共6列
[root@Kylin-V10-sp3 ~]# df -h | awk -F '[ %]+' 'NR>1 && $5>10 {print NF}'
6
[root@Kylin-V10-sp3 ~]# df -h | awk -F '[ %]+' 'NR>1 && $5>10 {print $0}'
/dev/sda1               1014M  151M  864M   15% /boot
[root@Kylin-V10-sp3 ~]# 

5.2 过滤某一列中有什么

根据指定的列进行过滤:如果第3列中包含xxxx则显示这一行.
sed,grep都是基于行,这一行中有或没有xxxx.
$xxx~// 匹配,包含
$xxx!~// 匹配,包含

点击查看代码
# /etc/passwd中第3列UID包含0或1,输出这一行的第1列,第3列和最后一列
[root@Kylin-V10-sp3 ~]# awk -F : '$3~/[01]/ {print $1,$3,$NF}' /etc/passwd | head -3
root 0 /bin/bash
bin 1 /sbin/nologin
operator 11 /sbin/nologin
[root@Kylin-V10-sp3 ~]# 
# /etc/passwd中第3列UID包含0或1结尾,输出这一行的第1列,第3列和最后一列
[root@Kylin-V10-sp3 ~]# awk -F : '$3~/[01]$/ {print $1,$3,$NF}' /etc/passwd | head -3
root 0 /bin/bash
bin 1 /sbin/nologin
operator 11 /sbin/nologin
# 过滤出access.log中第7列以.jpg或.bmp或.png或.gif结尾的行,统计行数.
'''
access.log nginx访问日志,只要访问就会有记录.
第1列 ip地址
第7列 用户访问的页面路径.
第9列 状态码,访问结果正常,异常.
第10列 页面大小
'''
[root@Kylin-V10-sp3 ~]# awk '$7~/\.(jpg|bmp|png|gif)$/' /opt/packages/access.log | wc -l
44235 
[root@Kylin-V10-sp3 ~]# awk '$7~/\.(jpg|bmp|png|gif)$/ {i++} END {print i}' /opt/packages/access.log
44235
[root@Kylin-V10-sp3 ~]# 

# 小结:
$xxx~//包含
!~不包含

6.总结

使用awk取行
使用awk取列
使用awk取行+取列
通过awk进行初步计算与统计(eg,统计次数(wc -l),求和)
i=i+1 === i++ 统计次数
i=i+$xxx 求和

四剑客 特点 擅长
find 找出文件 find与其他命令
grep 过滤 过滤速度快,检查正则.加上颜色.
sed 过滤 取行,替换(反向引用),修改文件内容
awk 过滤 取行,取列,计算
posted @ 2024-09-11 18:07  老虎死了还有狼  阅读(29)  评论(0编辑  收藏  举报