awk 使用进阶及使用案例

本文深入探讨了awk命令的高级应用技巧,包括格式化输出、变量定义、条件判断及循环结构等,通过多个实例展示了awk在处理文本和数据统计方面的强大能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. awk 使用进阶

1.1. 格式化输出 print 和 printf

  • print 函数 类似 echo

    # chen @ localhost in ~/Shell [18:25:12] 
    $ date | awk '{print "Month: "$2 "\nYear: " $1}' 
    Month: 12月
    Year: 2019年
    
  • printf 函数

    # chen @ localhost in ~/Shell [18:31:51] 
    $ awk 'BEGIN{FS=":"};{printf "%-15s %-15s %-15s\n",$1,$6,$NF}' passwd
    root            /root           /bin/zshi	     
    in              /bin            /sbin/nologin  
    ddaemon         /sbin           /sbin/nologin  
    adm             /var/adm        /sbin/nologin  
    sync            /sbin           /bin/sync	     
    shutdown        /sbin           /sbin/shutdown 
    
    • %s 字符类型
    • %d 数值类型
    • 15:占15个字符
    • “-” 表示左对齐,默认是右对齐
    • printf 默认不会在行尾自动换行,加 \n

1.2. 定义变量

# chen @ localhost in ~/Shell [18:36:13] 
$ awk -v NUM=3 -F: '{print NUM}' passwd
3
3
3
3
3
3
# 注意:awk中调用定义的变量不需要加$
# chen @ localhost in ~/Shell [18:37:04] 
$ awk -v NUM=3 -F: '{print $NUM}' passwd
0
1
2
3
5
6

1.3. BEGIN…END 使用

1.3.1. 概述
  • BEGIN :表示在程序开始前开始执行
  • END:表示所有文件处理完后执行
  • 用法: ' BEGIN {开始处理前}; {处理中}; END{处理结束后}'
1.3.2. 学习示例
  • 打印登录 shell 和 家目录

    # chen @ localhost in ~/Shell [19:07:33] 
    $ awk 'BEGIN {FS=":";print "Login shell\t\tLogin_home\n"};{ printf "%-25s %-25s\n", $1,$NF}; END{ print "****************************************"}' passwd
    Login shell		Login_home
    
    root                      /bin/zshi	               
    in                        /sbin/nologin            
    ddaemon                   /sbin/nologin            
    adm                       /sbin/nologin            
    sync                      /bin/sync	               
    shutdown                  /sbin/shutdown           
    ****************************************
    

2. awk 和正则的综合使用

  • == 等于
  • != 不等于
  • > 大于
  • < 小于
  • \~ 匹配
2.1. 学习示例
2.1.1. 打印以 root 开头或者以 adm 开头的行
# chen @ localhost in ~/Shell [19:25:20] C:130
$ awk '/^adm/ || /^root/ {print $0}' passwd
root:x:0:0:root:/root:/bin/zshi	
adm:x:3:4:adm:/var/adm:/sbin/nologin
# 方法2
# chen @ localhost in ~/Shell [19:25:23] 
$ awk '/^adm/;/^root/ {print $0}' passwd

2.1.2. 打印1到7行 以 bash 结尾的内容
# chen @ localhost in ~/Shell [19:30:14] 
$ awk 'NR>=2 && NR<=7 && $0 ~ /login$/{print $0}' passwd
in:x:1:1:bin:/bin:/sbin/nologin
ddaemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
# 方法2
# chen @ localhost in ~/Shell [19:30:19] 
$ awk 'NR>=2 && NR<=7 && /login$/{print $0}' passwd 
in:x:1:1:bin:/bin:/sbin/nologin
ddaemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

2.1.3. 获取电脑的 ip
# chen @ localhost in ~/Shell [19:34:07] 
$ ifconfig eth0 | grep broadcast
        inet 192.168.10.36  netmask 255.255.255.0  broadcast 192.168.10.255
# chen @ localhost in ~/Shell [19:38:03] 
$ ifconfig eth0 | grep broadcast | awk -F'[ ]+' '{print $3}'      
192.168.10.36

# 方法2
# chen @ localhost in ~/Shell [19:40:35] 
$ ifconfig eth0 | awk -F'[ ]+' '/broadcast/{print $3}'
192.168.10.36

# 方法3
# chen @ localhost in ~/Shell [19:41:36] 
$ ifconfig eth0 | awk -F'[ ]+' '/broadcast/{print $3RS$5RS$7}'
192.168.10.36
255.255.255.0
192.168.10.255

3. awk 条件判断

3.1. if结构
3.1.1. 语法结构
awk [选项] '正则','地址定位 {awk语句}' 文件名
3.1.2. 学习案例
# chen @ localhost in ~/Shell [19:47:31] 
$ awk -F: '{if ($3>=1 && $3<=5) {print $1,$3}}' passwd
in 1
ddaemon 2
adm 3
sync 5
3.2. if…else
3.2.1. 语法结构
awk [选项] '正则','地址定位 {awk语句}' 文件名

{ if (表达式) {语句;语句;...} else {语句;语句;...} }
3.2.2. 学习案例

判断用户是否为普通用户

# chen @ localhost in ~/Shell [21:42:30] 
$ awk -F: '{ if($3>=500 && $3!=65534) {print "普通用户"} else { print "不是普通用户"} }' passwd
不是普通用户
不是普通用户
不是普通用户
不是普通用户
不是普通用户
不是普通用户
3.3. if else if {} else if{}
3.3.1. 语法结构
awk [选项] '正则','地址定位 {awk语句}' 文件名

{ if (表达式) {语句;语句;...} else if (表达式2){语句;语句;...} else if (表达式2) {语句;语句...} ... else {语句;语句...} }
3.3.2. 学习案例

计算系统中管理员、系统用户、普通用户个数

# chen @ localhost in ~/Shell [21:54:20] 
$ awk -F: '{ if( $3==0 ) {i++} else if($3>=1 && $3<=499 || $3==65534) {j++} else {k++} }; END {print "管理员个数为: " i "\n系统用户个数为: "j "\n普通用户个数为: "k} ' passwd2
管理员个数为: 1
系统用户个数为: 4
普通用户个数为: 3

4. awk 循环结构

4.1. for结构
4.1.1. 语法结构
awk [选项] '正则','地址定位 {awk语句}' 

{ for (表达式) {语句;语句;... } } 
4.1.2. 学习案例
  • 打印1-10中的奇数

    # chen @ localhost in ~/Shell [9:56:49] C:1
    $ awk 'BEGIN { for(i=1;i<=10;i+=2) { print i } }'
    1
    3
    5
    7
    9
    
  • 计算1-5的和

    # chen @ localhost in ~/Shell [10:01:10] C:1
    $ awk 'BEGIN { sum=0; for(i=1;i<=5;i++) sum=sum+i; print sum }'    
    15
    # 方法2
    # chen @ localhost in ~/Shell [10:05:09] 
    $ for (( i=1;i<=5;i++ ));do echo $i; done | awk '{sum+=$0}; END {print sum }'
    15
    
4.2. while结构
4.2.1. 语法结构
awk [选项] '正则','地址定位 {awk语句}' 

{ while (表达式) {语句;语句;... } } 
4.2.2. 学习案例
  • 打印1-10中的奇数

    # chen @ localhost in ~/Shell [10:10:12] 
    $ awk 'BEGIN {i=1;sum=0; while(i<=5) {print i;i++}}'
    1
    2
    3
    4
    5
    
  • 计算1-5的和

    # chen @ localhost in ~/Shell [10:05:27] 
    $ awk 'BEGIN { i=0;sum=0; while(i<=5) {sum=sum+i;i++} print sum }'  
    15
    
4.3. 嵌套循环
学习案例

利用嵌套循环打印如下所示图形

5
54
543
5432
54321

# chen @ localhost in ~ [10:16:54] 
$ awk 'BEGIN { for (y=1;y<=5;y++){ for(x=1;x<=y;x++) {printf 6-x} print}  }' 
5
54
543
5432
54321

5. awk 统计案例

5.1. 统计系统中各种类型的 shell
# chen @ localhost in ~ [10:21:46] C:130
$ awk -F: '{shells[$NF]++}; END{ for(i in shells) {print i,shells[i] } }' /etc/passwd
/bin/sync 1
/sbin/nologin 43
/sbin/halt 1
/bin/zsh 2
/sbin/shutdown 1
5.2. 统计网站访问状态
# chen @ localhost in ~ [10:29:09] 
$ ss -an | grep :80 | awk '{ states[$2]++ };END {for(i in states) { print i, states[i]}}' | sort -k2 -rn
ESTAB 18
TIME-WAIT 13
LISTEN 10
5.3. 统计网站的每个 IP 的数量
# chen @ localhost in ~ [10:53:05] 
$ netstat -ant | grep :80 | awk -F ':' '{print $2}' | awk -F '[ ]+' '{ip_count[$2]++}; END {for (i in ip_count) {print "ip: "i"  |count: "ip_count[i]} }'
ip: 192.168.10.100  |count: 3
ip: 192.168.10.96  |count: 20
ip: 192.168.10.102  |count: 2
ip: 192.168.10.98  |count: 2
ip: 0.0.0.0  |count: 10
ip: 192.168.10.104  |count: 2
ip: 192.168.10.108  |count: 1

5.4. 统计 tomcat 网站日志中 PV 量
# chen @ localhost in /usr/local/tomcat/apache-tomcat-8.5.42/logs [10:57:50] 
$ awk -F'[ ]+' '{pv[$1]++}; END{for (i in pv) {print i, pv[i]}}' localhost_access_log.2019-09-11.txt
192.168.10.71 3
192.168.10.36 9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值