[Linux入门必备]17个案例带运维小白快速精通Awk命令,拿来即用!
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在对数据分析并生成报告时,显得尤为强大。
简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有三个不同的版本:awk、nawk和gawk,未作特别说明,一般指gawk,gawk是awk的GNU版本。
之所以叫awk是因为其取了三位创始人Alfred Aho,Peter Weinberger,和Brian Kernighan的Family Name的首字符。
awk格式:
1 2 3 4 5 6 7 8 9 10 | 格式: sed -n '3p' sed.txt 找谁干啥(条件动作) awk格式 #取出/etc/passwd 第1行的第1列和第3列 awk -F: 'NR==1{print $1,$3}' /etc/passwd awk 选项 '条件{动作}' /etc/passwd 条件: 哪一行,过滤什么内容 动作: print输出与显示 ,计算.... |
awk取行
与sed类似
案例01 取出sed.txt的第2行
1 2 3 4 5 6 7 8 9 10 11 12 13 | [root@oldboy81-golden-lnb /oldboy]# cat sed.txt 101,oldgirl,CEO 102,zhangya,CTO 103,lidao007,COO 104,yy,CFO 105,feixue,CIO 110,lidao,COCO [root@oldboy81-golden-lnb /oldboy]# awk 'NR==2' sed.txt 102,zhangya,CTO #awk '行号 等于 2' sed.txt #NR awk内置变量 Number of Record 记录号(行号) |
案例02 取出sed.txt中包含oldboy或lidao的行
1 2 3 4 5 6 | [root@oldboy81-golden-lnb /oldboy]# sed -rn '/oldboy|lidao/p' sed.txt 103,lidao007,COO 110,lidao,COCO [root@oldboy81-golden-lnb /oldboy]# awk '/oldboy|lidao/' sed.txt 103,lidao007,COO 110,lidao,COCO |
案例03 取出文件第2行到第5行内容
1 2 3 4 5 6 7 8 9 10 11 | #awk '行号大于等于2 并且 行号小于等于5' sed.txt #方法01 awk 'NR>=2 && NR<=5' sed.txt #必会 && 表示并且. #方法02 sed -n '2,5p' sed.txt #方法03 了解 awk 'NR==2,NR==5' sed.txt #从行号是2的行开始 到 行号是5的行结束( 了解) |
案例04 取出文件第3行到最后一行内容
1 2 3 4 5 6 7 8 9 10 | [root@oldboy81-golden-lnb /oldboy]# awk 'NR >= 3' sed.txt 103,lidao007,COO 104,yy,CFO 105,feixue,CIO 110,lidao,COCO [root@oldboy81-golden-lnb /oldboy]# sed -n '3,$p' sed.txt 103,lidao007,COO 104,yy,CFO 105,feixue,CIO 110,lidao,COCO |
案例05 取出从包含oldboy的行到lidao的行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [root@oldboy81-golden-lnb /oldboy]# cat sed.txt 101,oldgirl,CEO 102,zhangya,CTO 103,lidao007,COO 104,yy,CFO 105,feixue,CIO 110,lidao,COCO root@oldboy81-golden-lnb /oldboy]# sed -n '/old/,/lidao/p' sed.txt 101,oldgirl,CEO 102,zhangya,CTO 103,lidao007,COO [root@oldboy81-golden-lnb /oldboy]# awk '/old/ , /lidao/' sed.txt 101,oldgirl,CEO 102,zhangya,CTO 103,lidao007,COO |
awk取行小结
awk如何找出想要行?条件:
- 指定行号
NR==1
- 指定行号范围
NR>=3
或NR>=3 && NR<=5
- 过滤:
/oldby|lidao/
- 范围过滤:
/oldboy/,/lidao/
1 2 3 4 | [root@oldboy81-golden-lnb /oldboy]# awk '/11:02:00/,/11:02:30/' access.log |wc -l 1415 [root@oldboy81-golden-lnb /oldboy]# awk '/00/,/30/' access.log |wc -l 166945 |
awk取列
目标:熟练取出指定的内容或部分(取列)
1 2 3 | #awk取列格式 awk '{print $1,$3}' oldboy.txt |
案例01 取出ls -lh命令中的第1列和第3列
1 | ll -h | awk '{print $1,$3}' |
注意:awk 中
$数字只有一个意思,取列
案例02 取出/etc/passwd每一行内容,加上行号
1 2 3 4 5 6 7 8 | #方法01 cat -n /etc/passwd #方法02 awk '{print NR,$0}' /etc/passwd NR 表示行号. $0 表示一整行内容. |
案例03 取出/etc/passwd第1列和第3列
awk取列的,默认以空格,连续空格或tab键空格分割. 只需要使用3,$6....即可取出
如果想更改或指定新的,分隔符,需要使用 -F
选项
-F指定分隔符,-F指定正则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@oldboy81-golden-lnb /oldboy]# head /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/ var /adm:/sbin/nologin lp:x:4:7:lp:/ var /spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/ var /spool/mail:/sbin/nologin operator :x:11:0: operator :/root:/sbin/nologin awk -F ':' '{print $1,$3}' /etc/passwd awk -F ':' '{print $1,$3}' /etc/passwd |column -t |
案例04 取出ip.txt文件中ip(10.0.0.200)地址
awk中指定多个分隔符,需要使用正则匹配这多个分隔符即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | echo ' inet 10.0.0.200/24 brd 10.0.0.255 scope global ens33' >/oldboy/ip.txt #方法01 多个管道 第1步骤: awk取第2列 第2步骤: awk指定分隔符取第1列. [root@oldboy81-golden-lnb /oldboy]# cat ip.txt inet 10.0.0.200/24 brd 10.0.0.255 scope global ens33 [root@oldboy81-golden-lnb /oldboy]# awk '{print $2}' ip.txt 10.0.0.200/24 [root@oldboy81-golden-lnb /oldboy]# awk '{print $2}' ip.txt |awk -F '/' '{print $1}' 10.0.0.200 #方法02 awk直接取出 指定多个分隔符 ※※※※※ 需要使用正则 ###01) [root@oldboy81-golden-lnb /oldboy]# awk -F 'inet |/24' '{print $2}' ip.txt 10.0.0.200 ###02) [root@oldboy81-golden-lnb /oldboy]# cat ip.txt inet 10.0.0.200/24 brd 10.0.0.255 scope global ens33 [root@oldboy81-golden-lnb /oldboy]# awk -F '[ /]+' '{print $3}' ip.txt 10.0.0.200 #-F '[ /]+' 先用正则匹配出连续出现的空格或/. 然后交给awk -F作为分隔符. #方法03 awk+sed .....略 自己书写 |
案例05 取出/etc/passwd第1列,第3列和最后一列
- $NF 最后一列
- NF Number of Field 每行有多少个字段(域,列) 每行有多少列
1 2 | #awk -F':' '{print $1,$3,$NF}' /etc/passwd awk -F ':' '{print $1,$3,$NF}' /etc/passwd |
awk行列综合(awk过滤进阶)
精确过滤必备
- awk可以完成,某一列中包含/不包含内容..
$3 ~ // 匹配或包含
$3 !~ // 不匹配或不包含
1 2 3 4 5 6 | 格式: awk -F: '第3列 包含 以1或2开头的内容' passwd #示例: 取出passwd中第3列以1或2开头内容,显示这一行 awk -F: '$3 ~ /^[12]/' passwd |
案例01 过滤出passwd中第3列以0到3结尾的,显示第1列和第3列内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 条件: 第3列以0到3结尾 (取行) 动作: 显示第1列和第3列 (取列) #方法01 分步骤 awk -F: '$3~/[0-3]$/' passwd awk -F: '$3~/[0-3]$/' passwd |awk -F: '{print $1,$3}' #方法02 awk同时取行与取列 awk -F: 'NR==1{print $1,$3}' /etc/passwd awk 选项 '条件{动作}' /etc/passwd awk -F: '$3~/[0-3]$/ {print $1,$3} ' passwd 条件 {动作} |
案例02 过滤passwd中第3列大于0小于1000内容,显示第1列和第3列
1 2 3 4 5 6 7 8 9 | #条件(取行): 过滤passwd中第3列大于0小于1000内容 #动作(取列): 显示第1列和第3列 #条件(取行): 过滤passwd中第3列大于0小于1000内容 awk -F: '$3>0 && $3<1000' passwd #动作(取列): 显示第1列和第3列 awk -F: '$3>0 && $3<1000{print $1,$3}' passwd awk -F: '$3>0 && $3<1000{print $1,$3}' passwd |column -t |
案例03 过滤出网卡配置文件中的ip地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /etc/sysconfig/network-scripts/ifcfg-ens33 (eth0) #李导建议: 如果要求中没有明确写出条件(eg,行号,过滤包含xxx) 需要查看文件内容分析,(使用固定行号,过滤xxxx内容). [root@oldboy81-golden-lnb /oldboy]# cat -n /etc/sysconfig/network-scripts/ifcfg-ens33 1 TYPE=Ethernet 2 PROXY_METHOD=none 3 BROWSER_ONLY=no 4 BOOTPROTO=none 5 DEFROUTE=yes 6 IPV4_FAILURE_FATAL=no 7 IPV6INIT=yes 8 IPV6_AUTOCONF=yes 9 IPV6_DEFROUTE=yes 10 IPV6_FAILURE_FATAL=no 11 IPV6_ADDR_GEN_MODE=stable-privacy 12 NAME=ens33 13 UUID=8e987179-762e-466e-aa40-fe38ebb012d0 14 DEVICE=ens33 15 ONBOOT=yes 16 IPADDR=10.0.0.200 17 PREFIX=24 18 GATEWAY=10.0.0.2 19 DNS1=223.5.5.5 20 IPV6_PRIVACY=no #条件: 方法01:取出第16行 方法02:过滤包含IPADDR=的行 #动作: 显示第2列(以=分割) awk #方法01 16行 [root@oldboy81-golden-lnb /oldboy]# awk -F= 'NR==16' /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=10.0.0.200 [root@oldboy81-golden-lnb /oldboy]# awk -F= 'NR==16 {print $2}' /etc/sysconfig/network-scripts/ifcfg-ens33 10.0.0.200 #方法02 过滤IPADDR awk -F= '/IPADDR/ {print $2}' /etc/sysconfig/network-scripts/ifcfg-ens33 sed #方法01 16行 [root@oldboy81-golden-lnb /oldboy]# sed -n '16p' /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=10.0.0.200 [root@oldboy81-golden-lnb /oldboy]# sed -n '16p' /etc/sysconfig/network-scripts/ifcfg-ens33|sed 's#^.*=##g' 10.0.0.200 [root@oldboy81-golden-lnb /oldboy]# sed -n '16 s#^.*=##g p' /etc/sysconfig/network-scripts/ifcfg-ens33 10.0.0.200 [root@oldboy81-golden-lnb /oldboy]# [root@oldboy81-golden-lnb /oldboy]# ip a s ens33 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:e8:3a:6f brd ff:ff:ff:ff:ff:ff inet 10.0.0.200/24 brd 10.0.0.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fee8:3a6f/64 scope link valid_lft forever preferred_lft forever [root@oldboy81-golden-lnb /oldboy]# ip a s ens33 |sed -n '3p' inet 10.0.0.200/24 brd 10.0.0.255 scope global ens33 [root@oldboy81-golden-lnb /oldboy]# ip a s ens33 |sed -n '3p' |sed -r 's#^.*et (.*)/.*$#\1#g' 10.0.0.200 [root@oldboy81-golden-lnb /oldboy]# [root@oldboy81-golden-lnb /oldboy]# ip a s ens33 |sed -nr '3 s#^.*et (.*)/.*$#\1#g p' 10.0.0.200 #方法02 过滤IPADDR sed -n '/IPADDR/ s#^.*=##g p' /etc/sysconfig/network-scripts/ifcfg-ens33 |
awk统计计算功能
BEGIN{}和END{}
- awk中的特殊的条件(模式),pattern
- 这两个特殊的条件,都与计算相关,最常用的是END{}
特殊条件(模式) | 含义 | 应用场景 |
---|---|---|
BEGIN{} | BEGIN{}内容会在awk读取文件之前执行 | 1. 里面进行实验;2.进行计算,不需要读取文件内容;3. 创建或修改awk变量 |
END{} | END{}内容会在awk读取文件之后执行 | 1. awk在读取文件的时候进行统计与计算. 最后统计完成在END{}输出最终结果 |
BEGIN{}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #计算 1/3 + - * / [root@oldboy81-golden-lnb /oldboy]# awk 'BEGIN{ print 1/3}' 0.333333 [root@oldboy81-golden-lnb /oldboy]# awk 'BEGIN{ print 1/3,1-3,1+3,3*3}' 0.333333 -2 4 9 [root@oldboy81-golden-lnb /oldboy]# awk 'BEGIN{ print 1/3,1-3,1+3,3*3,2^10}' 0.333333 -2 4 9 1024 #修改awk变量 了解 awk -F: 'NR==1{print $1}' passwd awk 'BEGIN{FS=":"} NR==1{print $1}' passwd |
END{}
案例01 统计/etc/passwd的行数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | wc -l /etc/passwd #条件: 无 #动作: i++ #统计次数,类似于wc -l awk '{i++}' /etc/passwd #输出最后i内容. awk '{i++} END{print i}' /etc/passwd #完成 #详解 i++ i=i+1 === i++ #功能用于计数,统计有多少次,一共出现的次数.... 类似于 wc -l cat num.txt a b c d e awk '{i++} END{print i}' num.txt 之前的i内容 i=i+1 之后i的内容 读1行 空/0 i=0+1 1 第2行 1 i=1+1 2 第3行 2 i=2+1 3 第4列 3 i=3+1 4 ....... |
案例02 统计/etc/passwd中可登录用户数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 可登录的用户: 命令解释器是/bin/bash #条件: 命令解释器是bash #动作: c++ #统计次数,类似于wc -l #输出最后次数/数量. END{print c} #条件: 命令解释器是bash awk ' {i++} END{print i}' /etc/passwd awk '/bash$/ {c++} END{print c}' /etc/passwd #awk执行的时候,统计的时候 输出过程 熟悉 awk '/bash$/ {c++;print c} ' passwd |
案例03 统计/etc/services文件中空行的数量
1 2 3 4 5 6 7 8 9 10 | #条件: 过滤空行 ^$ #动作: j++ #统计次数,类似于wc -l #输出最后次数/数量. [root@oldboy81-golden-lnb /oldboy]# #awk '/^$/' /etc/services [root@oldboy81-golden-lnb /oldboy]# [root@oldboy81-golden-lnb /oldboy]# awk '/^$/{j++} ' /etc/services [root@oldboy81-golden-lnb /oldboy]# [root@oldboy81-golden-lnb /oldboy]# awk '/^$/{j++} END{print j}' /etc/services 17 |
案例04 生产工作案例 统计access.log中一共用了多少流量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 文件中记录着用户每天流量.求和,累加. cat > liu.log<<EOF 1 5 0.5 10 100 200 300 EOF i=i+1 == i++ sum=sum+$1或$0 之前的sum内容 sum=sum+$1 之后sum的内容 第1行 0 sum=0+1 1 第2行 1 sum=1+5 6 第3行 6 sum=6+0.5 6.5 第4行 6.5 sum=6.5 + 10 16.5 sum=sum+$xxx #累加或求和. [root@oldboy81-golden-lnb /oldboy]# cat liu.log 1 5 0.5 10 100 200 300 [root@oldboy81-golden-lnb /oldboy]# awk '{sum=sum+$1} END{print sum}' liu.log 616.5 |
awk常见环境变量
环境变量 | 含义 |
---|---|
NR | 行号 |
NF | 每行有多少列 |
$NF | 表示最后一列 |
$数字 | 2 取出某一列或某几列. 一般配合-F一起使用 |
$0 | 每行的所有列(一整行内容) |
FS | field separator字段(列)分隔符,分隔符.-F背后修改的内容 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?