当前位置: 首页 > news >正文

深入理解awk

深入理解 AWK:文本处理的强大工具

在 Linux 系统的文本处理工具中,AWK 以其强大的功能和灵活性占据着重要地位。它不仅能进行简单的文本过滤,还能实现复杂的格式化处理、数据统计等操作,是系统管理员和开发人员日常工作中的得力助手。本文将带您深入了解 AWK 的核心功能、使用方法及实际应用案例。

AWK 的基本流程

AWK 的处理流程主要分为三个部分,分别是 BEGIN 语句块、pattern 语句块和 END 语句块,其基本格式如下:

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

这三个部分的执行顺序和功能如下:

  1. 第一步:运行 BEGIN{ commands } 语句块中的语句。该语句块在 AWK 开始从输入流中读取行之前被运行,常用于变量初始化、打印输出表格的表头等操作,是一个可选的语句块。
  2. 第二步:从文件或标准输入(stdin)读取一行,然后运行 pattern{ commands } 语句块。它会逐行扫描文件,从第一行到最后一行反复这个过程,直到文件所有内容被读取完成。该语句块也是可选的,如果没有提供,则默认运行 { print },即打印每个读取到的行。
  3. 第三步:当读至输入流末尾时,运行 END{ commands } 语句块。该语句块在 AWK 从输入流中读取完全部的行之后运行,常用于打印全部行的分析结果等信息汇总操作,同样是可选的语句块。

需要注意的是,这三个部分缺少任何一部分都是可以的,具体使用哪个部分取决于实际需求。

AWK 常用操作案例

基本匹配与统计

  • 统计 /etc/passwd 文件中以 /bin/bash 结尾的行数:

    [root@localhost ~]#awk 'BEGIN{x=0};/\/bin\/bash$/ {x++;print x,$0};END {print x}' /etc/passwd
    

    在这里插入图片描述

    该命令等同于 grep -c "/bin/bash$" /etc/passwd。在 BEGIN 模式中初始化变量 x 为 0,然后逐行扫描文件,当遇到以 /bin/bash 结尾的行时,变量 x 加 1 并打印相关信息,最后在 END 模式中打印统计的总行数。

  • 输出 /etc/passwd 文件中第 3 个字段的值不小于 200 的行:

    [root@localhost ~]#awk -F ":" '! ($3<200){print} ' /etc/passwd
    

    在这里插入图片描述

    这里使用 -F ":" 指定字段分隔符为冒号,! ($3<200) 表示第 3 个字段的值不小于 200,然后打印满足条件的行。

  • 先处理 BEGIN 中的内容,再打印 /etc/passwd 文件中第 3 个字段的值大于等于 1000 的行:

    [root@localhost ~]#awk 'BEGIN {FS=":"} ;{if($3>=1000){print}}' /etc/passwd 
    

    在这里插入图片描述

    BEGIN 语句块中设置字段分隔符为冒号,然后使用 if 条件判断打印满足第 3 个字段的值大于等于 1000 的行。

行号与字段操作

  • 输出 /etc/passwd 文件中每行内容和行号:

    [root@localhost ~]#awk -F ":" '{print NR,$0}' /etc/passwd
    

    在这里插入图片描述

    其中 NR 表示当前处理的行的行号,每处理完一条记录,NR 值加 1。该命令等同于 sed -n '=;p' /etc/passwd

  • 输出 /etc/passwd 文件中以冒号分隔且第 7 个字段中包含 bash 的行的第 1 个字段:

    [root@localhost ~]#awk -F ":" '$7~"bash"{print $1,47}' /etc/passwd
    

    在这里插入图片描述

    也可以使用 awk -F: '/bash/ {print $1}' /etc/passwd 实现类似功能,$7~"bash" 表示第 7 个字段包含 bash 字符串。

  • 输出 /etc/passwd 文件中第 1 个字段中包含 root 且有 7 个字段的行的第 1、2 个字段:

    [root@localhost ~]#awk -F":" '($1~"root") && (NF==7) {print $1,$2,$NF } ' /etc/passwd
    

    在这里插入图片描述

    NF 表示当前行的字段总数,$NF 表示最后一个字段。

多条件筛选

  • 输出 /etc/passwd 文件中第 7 个字段既不为 /bin/bash,也不为 /sbin/nologin 的所有行:
    [root@localhost ~]#awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print} ' /etc/passwd
    
    在这里插入图片描述

与 Shell 命令结合

  • 统计以冒号分隔的文本段落数(以 $PATH 为例):

    [root@localhost ~]#echo $PATH | awk 'BEGIN{RS=":"};END {print NR}'   
    

    RS 表示记录分隔符,这里设置为冒号,NR 在最后会表示分隔后的段落数。

  • 调用 wc -l 命令统计 /etc/passwd 文件中使用 bash 的用户个数:

    [root@localhost ~]#awk -F: '/bash$/{print | "wc -l"}' /etc/passwd 
    

    在这里插入图片描述

    该命令等同于 grep -c "bash$" /etc/passwdawk -F: '/bash$/ {print}' /etc/passwd | wc -l

系统资源监控案例

  • 查看当前内存使用百分比:

    [root@localhost ~]#free -m |awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'
    

    在这里插入图片描述

    先通过 free -m 查看内存使用情况,然后使用 AWK 提取相关字段计算内存使用百分比,int 函数用于取整数部分。

  • 查看当前 CPU 空闲率:

    [root@localhost ~]#top -b -n 1 | grep Cpu | awk -F ',' '{print $4}'| awk '{print $1}'
    

    在这里插入图片描述

    top -b -n 1 表示只需要 1 次的输出结果,然后通过 AWK 提取 CPU 空闲率相关字段。

  • 调用 w 命令统计在线用户数:

    [root@localhost ~]# awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'
    

    在这里插入图片描述

    使用 getlinew 命令的输出中读取内容并进行统计。

  • 调用 hostname 命令并输出当前的主机名:

    [root@localhost ~]#awk 'BEGIN { "hostname" | getline ; {print $0}}'
    

    在这里插入图片描述

AWK 数组与循环

数组基本操作

AWK 数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号。例如:

[root@localhost ~]#awk 'BEGIN{a[0]=10;a[1]=20;print a[1]}'
[root@localhost ~]#awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["abc"]}'
[root@localhost ~]#awk 'BEGIN{a["abc"]="aabbcc";a["xyz"]="xxyyzz";print a["xyz"]}'

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结合数组和循环的案例

  • 遍历数组并打印下标和对应的值:

    [root@localhost ~]# awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print i,a[i]}}'
    

    在这里插入图片描述

  • 统计 httpd 访问日志中每个客户端 IP 的出现次数:

    [root@localhost ~]# awk '{a[$1]+=1;} END {for(i in a){print a[i]" "i;}}' /var/log/httpd/access_log | sort -r
    

    定义数组 a,数组的下标为日志文件的第 1 列(即客户端的 IP 地址),a[$1]+=1 表示对客户端进行统计计数,客户端 IP 出现一次计数器就加 1。END 中的指令在读取完文件后执行,通过循环将所有统计信息输出并按出现次数降序排序。

  • 统计 /var/log/secure 文件中登录失败的 IP 及其次数:

    [root@localhost ~]# awk '/Failed password/{ip[$11]++}END{for(i in ip){print i","ip[i]}}' /var/log/secure
    

生产脚本编写示例

以下是一个根据登录失败次数进行警告的脚本:

#!/bin/ bash
x=`awk '/Failed password/{ip[$11]++}END{for(i in ip){print i","ip[i]}}' /var/log/secure`
#190.168.10.22 3
for j in $x
do
ip=`echo $j | awk -F "," '{print $1}'`
num=`echo $j | awk -F "," '{print $2}'`
if [ $num -ge 3 ];then
echo "警告! $ip访问本机失败了$num次,请速速处理!"
fi
done

该脚本先通过 AWK 统计 /var/log/secure 文件中登录失败的 IP 及其次数,然后遍历统计结果,当失败次数大于等于 3 时,输出警告信息。

提取版本号案例

对于以下文件内容,提取版本号:

ant-1.9.7.jar
ant-launcher-1.9.7.jar
antlr-2.7.7.jar
antlr-runtime-3.4.jar
aopalliance-1.0.jar
archaius-core-0.7.6.jar
asm-5.0.4.jar
aspectjweaver-1.9.5.jar
bcpkix-jdk15on-1.64.jar
bcprov-jdk15-1.46.jar
bcprov-jdk15on-1.64.jar
checker-compat-qual-2.5.5.jar

可以使用以下命令:

[root@localhost /]#cat 1.txt |sed -r 's/.*-(.*)\.jar/\1/'

该命令使用 sed 命令的正则替换功能,提取出 .jar 文件名中 - 后面的版本号部分。

总结

  • grep 和 egrep:更适合单纯的查找或匹配文本。
  • sed:流编辑器,更适合编辑匹配到的文本。
  • awk:文本报告生成器,更适合格式化文本,对文本进行较复杂格式处理。

通过本文的介绍,相信您对 AWK 有了更深入的了解。在实际工作中,灵活运用 AWK 的各种功能,可以大大提高文本处理的效率。希望这些内容能帮助您更好地掌握 AWK 这一强大的工具。


文章转载自:

http://bW15FtTc.pqqzd.cn
http://bJSbzDiU.pqqzd.cn
http://lCcyhDy9.pqqzd.cn
http://ln1vzrtY.pqqzd.cn
http://94GqKmFY.pqqzd.cn
http://SlwA0424.pqqzd.cn
http://yHaqq029.pqqzd.cn
http://wB6eJxyE.pqqzd.cn
http://Y2YJsDXc.pqqzd.cn
http://6VO7mZKA.pqqzd.cn
http://DqImI76t.pqqzd.cn
http://wlJR0cI8.pqqzd.cn
http://a8TxNxn9.pqqzd.cn
http://u9r1mFnl.pqqzd.cn
http://dy5XIxb9.pqqzd.cn
http://s9mYMJTV.pqqzd.cn
http://Ikpz3Rs7.pqqzd.cn
http://yBCH66hU.pqqzd.cn
http://RBMiUf9b.pqqzd.cn
http://PrP10v3M.pqqzd.cn
http://lzKMF4OT.pqqzd.cn
http://cAK0HPOg.pqqzd.cn
http://Pq2aq57V.pqqzd.cn
http://Pq0NIiDW.pqqzd.cn
http://Y1BYLp7h.pqqzd.cn
http://3hte09zq.pqqzd.cn
http://xe0Dkswk.pqqzd.cn
http://CiK0foeZ.pqqzd.cn
http://1KX5Ii4L.pqqzd.cn
http://jMARrGrI.pqqzd.cn
http://www.dtcms.com/a/367651.html

相关文章:

  • Leetcode 206. 反转链表 迭代/递归
  • RFID+工业互联网:汽车全景天幕全生命周期智能检测体系构建
  • javaweb基础第一天总结(HTML-CSS)
  • Django全局异常处理全攻略
  • 阵列信号处理之均匀面阵波束合成方向图的绘制与特点解读
  • 钉钉 AI 深度赋能制造业 LTC 全流程:以钉钉宜搭、Teambition 为例
  • JS对象进阶
  • 【109】基于51单片机自动感应迎宾门【Proteus仿真+Keil程序+报告+原理图】
  • 来自AI的背包系统
  • 【操作系统-Day 24】告别信号量噩梦:一文搞懂高级同步工具——管程 (Monitor)
  • 前端url参数拼接和提取
  • Qt 中添加并使用自定义 TTF 字体(以 Transformers Movie 字体为例)
  • 基于STM32的智能家居环境监控系统设计
  • 什么是静态住宅IP 跨境电商为什么要用静态住宅IP
  • 3 步搞定顶刊科研插图!用 GPT-5 反推提示词,Nano Banana 模型一键出图,附实操演示
  • Tengine/Nginx 安装以及模块查看与扩展
  • 新一代实时检测工具——YOLOv13本地部署教程,复杂场景,一目了然!
  • html学习:
  • 多线程顺序打印ABC的两种实现方式:synchronized与Lock机制
  • 苍穹外卖优化过程遇到的问题
  • android源码角度分析Handler机制
  • 25高教社杯数模国赛【E题保姆级思路+问题分析】
  • 政务级数据安全!小陌GEO引擎的私有化部署实践指南
  • 卫星通信+地面网络融合 Sivers半导体毫米波技术打通智慧交通最后一公里
  • 理解进程栈内存的使用
  • C4.5决策树(信息增益率)、CART决策树(基尼指数)、CART回归树、决策树剪枝
  • 前端vue常见标签属性及作用解析
  • Vue基础知识-脚手架开发-子传父-props回调函数实现和自定义事件($on绑定、$emit触发、$off解绑)实现
  • 铭记抗战烽火史,科技强企筑强国 | 金智维开展抗战80周年主题系列活动
  • 无人机信号防干扰技术难点分析