Linux awk命令完全指南:从原理到实战,搞定文本处理难题

在Linux世界里,文本处理是运维、开发绕不开的日常——从分析日志、提取配置信息到统计数据,都需要高效的工具支撑。而awk,作为一款强大的文本分析语言,凭借“按字段处理”的核心能力,成为了比grep(单纯匹配)、sed(整行编辑)更灵活的“文本处理瑞士军刀”。今天这篇文章,我们从原理到实战,带你彻底掌握awk的用法,解决90%的文本处理场景。

一、认识awk:它是什么,从哪里来?

awk并非简单的命令,而是一门专为文本处理设计的编程语言,诞生于20世纪70年代的贝尔实验室,名字取自三位创始人Alfred AhoPeter WeinbergerBrian Kernighan的姓氏首字母。

1.1 awk的版本区别

在Linux系统中,我们实际使用的awk大多是GNU awk(gawk)——因为所有GNU/Linux发行版(如CentOS、Ubuntu)都自带gawk,且它完全兼容早期的AWK(AT&T原版)和NAWK(New AWK,原版升级版)。
你可以通过以下命令验证:

# 查看awk的实际路径
which awk  # 输出:/usr/bin/awk
# 查看是否为gawk的软链接
ll `which awk`  # 输出:lrwxrwxrwx. 1 root root 4 ... /usr/bin/awk -> gawk

在这里插入图片描述

简单说:在Linux中输入awk命令,实际执行的是gawk

二、awk的核心:工作原理与流程

要用好awk,必须先理解它的“做事逻辑”——这也是它和sed最大的区别:

  • sed:以“整行”为单位处理文本;
  • awk:先将每行拆分为“字段”(默认用空格/制表符分隔),再按字段处理,支持逻辑判断、数学运算。

2.1 工作原理

awk的处理流程可以概括为“逐行读取→字段拆分→条件匹配→执行操作”:

  1. 从标准输入(如管道)或文件中逐行读取文本
  2. 按默认分隔符(空格/制表符)或自定义分隔符,将当前行拆分为多个“字段”,用$1(第一列)、$2(第二列)…$n(第n列)表示,$0表示整行;
  3. 根据指定的“模式”(如包含某个关键词、行号范围)判断是否处理当前行;
  4. 若匹配模式,执行指定的“动作”(如打印字段、统计计数);
  5. 重复1-4,直到文件读取完毕。

2.2 三大核心模块:BEGIN → 主体 → END

awk的脚本结构由三个可选模块组成,执行顺序严格固定,这是它的灵魂:

模块执行时机作用示例
BEGIN读取文本前执行(仅1次)初始化变量、打印表头
主体逐行读取文本时执行(每行会触发)字段提取、条件判断
END读取文本后执行(仅1次)汇总统计结果、打印最终值

用流程图理解更直观:

开始 → 执行BEGIN模块 → 读取一行文本 → 执行主体模块(按模式处理) → 文件是否结束?↑                      ↓└──────────────────────┘(否)↓(是)执行END模块 → 结束

三、awk基础:语法与核心内置变量

掌握语法和内置变量,是玩转awk的第一步。

3.1 基本语法

awk有两种常用命令格式,根据场景选择:

格式1:直接在命令行写逻辑
awk [选项] '模式{动作}' 文件名1 文件名2...
  • 选项:常用-F指定字段分隔符(如-F:表示用冒号分隔);
  • 模式:可选,如行号(NR==5)、关键词匹配(/root/);
  • 动作:必须用{}包裹,如print $1(打印第一列)、变量运算。
格式2:用脚本文件(适合复杂逻辑)

当逻辑复杂时,将模式和动作写入脚本文件,用-f指定:

awk -f 脚本文件 文件名

3.2 必学内置变量

awk预定义了一批“开箱即用”的变量,覆盖90%的实战场景,务必牢记:

内置变量含义说明实战常用场景
FS输入字段分隔符(默认:空格/制表符)BEGIN{FS=“:”}(用冒号分隔)
NF当前行的字段总数(列数)打印最后一列:print $NF
NR当前处理的行号(所有文件统一计数)打印前5行:NR<=5
FNR当前处理的行号(每个文件单独计数)多文件对比时用
$0当前处理的整行内容打印整行:print $0
$n当前行的第n个字段(n为数字,如$1是第一列)提取用户名:print $1
OFS输出字段分隔符(默认:空格)输出用“—”分隔:BEGIN{OFS=“—”}
FILENAME当前处理的文件名多文件处理时标记来源

四、awk实战:从基础到生产级案例

理论讲完,直接上案例——这些场景都是Linux运维/开发的高频需求,跟着练一遍就能上手。

4.1 基础案例:字段提取与格式控制

案例1:提取/etc/passwd的关键信息

/etc/passwd用冒号分隔,包含用户名、UID、家目录等信息,用awk轻松提取:

# 1. 用冒号分隔,打印用户名($1)和家目录($6),输出用制表符分隔
awk -F: '{print $1 "\t" $6}' /etc/passwd
# 输出示例:
# root    /root
# bin     /bin

在这里插入图片描述

# 2. 只打印包含“root”的行,且显示行号(NR)
awk -F: '/root/{print NR, $1, $6}' /etc/passwd
# 输出示例:
# 1 root /root
# 10 operator /root# 3. 打印最后一列(登录Shell),并标注“行号-列数”
awk -F: '{print "第" NR "行,共" NF "列,Shell:" $NF}' /etc/passwd

在这里插入图片描述

案例2:自定义多分隔符

如果文本用多种符号分隔(如:/),可在-F后用[]指定:

# 用“:”或“/”分隔,打印第9列(适用于/etc/passwd的Shell路径提取)
awk -F[:/] '{print $9}' /etc/passwd
# 输出示例:
# bash
# nologin

在这里插入图片描述

4.2 进阶案例:条件判断与统计

案例1:数值与字符串比较

awk支持数值比较(==<>>=)和字符串精确匹配(需加引号):

# 1. 打印UID=0的用户(管理员用户,$3是UID)
awk -F: '$3==0{print $1 "是管理员"}' /etc/passwd
# 输出:root是管理员# 2. 打印UID>=1000的普通用户($3>=1000)
awk -F: '$3>=1000{print $1 "是普通用户,UID:" $3}' /etc/passwd# 3. 精确匹配用户名“root”(字符串必须加双引号!)
awk -F: '$1=="root"{print $0}' /etc/passwd

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

案例2:模糊匹配(~ 和 !~)

~表示“包含”,!~表示“不包含”,结合正则表达式使用:

# 1. 打印Shell包含“bash”的用户(即能登录的用户)
awk -F: '$7~"bash"{print $1}' /etc/passwd# 2. 打印Shell不包含“nologin”且不包含“bash”的用户
awk -F: '$7!~"nologin" && $7!~"bash"{print $1}' /etc/passwd

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

案例3:用BEGIN/END做统计汇总

BEGIN初始化变量,END输出最终结果,适合统计场景:

# 1. 统计/etc/passwd的总行数(END中用NR,因为NR是总计数)
awk 'END{print "/etc/passwd共有" NR "行"}' /etc/passwd# 2. 统计能登录的用户数(Shell为bash)
awk -F: 'BEGIN{count=0} $7~"bash"{count++} END{print "能登录的用户数:" count}' /etc/passwd# 3. 计算1-10的总和(BEGIN中用循环)
awk 'BEGIN{sum=0; for(i=1;i<=10;i++){sum+=i}; print "1-10总和:" sum}'

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

4.3 生产级案例:系统监控与日志分析

awk常与其他命令结合,实现系统监控和日志统计,这是运维的核心技能。

案例1:查看内存使用率

free -m获取内存信息,awk计算使用率:

# 计算内存使用率(已用/总内存 *100,保留整数)
free -m | awk '/Mem:/ {used=$3; total=$2; rate=int(used/total*100); print "内存使用率:" rate "%"}'
# 输出:内存使用率:35%

在这里插入图片描述

4.4 扩展生产案列:网卡的ip、流量

[root@localhost ~]# ifconfig ens33 | awk '/netmask/{print "本机的ip地址是"$2}' 

在这里插入图片描述

[root@localhost ~]# ifconfig ens33 | awk '/RX p/{print $5"字节"}'

在这里插入图片描述

[root@localhost ~]# df -h | awk 'NR==2{print $4}'

在这里插入图片描述

4.5 逻辑运算

[root@localhost ~]# awk -F: '$3<10 || $3>=1000' /etc/passwd
[root@localhost ~]# awk -F: '$3>10 && $3<1000' /etc/passwd
[root@localhost ~]# awk -F: 'NR>4 && NR<10' /etc/passwd

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

4.6 其他内置变量

其他内置变量的用法FS(输入)、OFS、NR、FNR、RS、ORSFS:输入字段的分隔符 默认是空格OFS:输出字段的分隔符 默认也是空格
FNR:读取文件的记录数(行号),从1开始,新的文件重新重1开始计数
RS:输入行分隔符 默认为换行符
ORS:输出行分隔符 默认也是为换行符

五、高级用法:逻辑控制与数组

5.1 awk高级用法 if语句

awk的if语句与其他编程语言类似,支持单分支、双分支两种常见形式,可根据字段内容或行号等条件执行不同操作,适用于需要条件筛选的文本处理场景。

  • 单分支if语句:仅当条件成立时执行动作,常用于筛选符合条件的行。
    示例:筛选/etc/passwd中第三列(UID)小于10的行(系统用户)并打印整行,命令如下:
    `[root@localhost ~]# awk -F: '{if($3<10){print $0}}' /etc/passwd`

在这里插入图片描述

  • 双分支if-else语句:条件成立时执行一个动作,不成立时执行另一个动作,适用于二选一的处理场景。
    示例:处理/etc/passwd时,若第三列(UID)小于10则打印第三列,否则打印第一列(用户名),命令如下:
    [root@localhost ~]# awk -F: '{if($3<10){print $3}else{print $1}}' /etc/passwd

在这里插入图片描述

5.2 扩展 AWK 数组

awk的数组具有灵活的下标特性,不仅支持数字下标,还支持字符串下标(字符串需用双引号包裹),且无需预先定义数组长度,可动态存储数据,常用于统计、去重等场景。

数组核心特点与基础示例

  • 下标类型:数字下标用于有序数据存储,字符串下标用于关联数据(如“键-值”对)存储。
  • BEGIN模块特性:BEGIN中的命令仅执行一次,适合数组初始化操作。

基础示例:

  1. 数字下标数组:初始化数组a,下标为0和1,分别赋值10和20,打印指定下标值:
    [root@localhost ~]# awk 'BEGIN{a[0]=10;a[1]=20;print a[1]}'(输出20)
    [root@localhost ~]# awk 'BEGIN{a[0]=10;a[1]=20;print a[0]}'(输出10)。
    在这里插入图片描述
    在这里插入图片描述

  2. 字符串下标数组:初始化数组a,下标为字符串“abc”和“xyz”,分别赋值10、20或字符串,打印指定下标值:
    [root@localhost ~]# awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["abc"]}'(输出10)
    [root@localhost ~]# awk 'BEGIN{a["abc"]="aabbcc";a["xyz"]="xxyyzz";print a["xyz"]}'(输出xxyyzz)。
    在这里插入图片描述

5.3 扩展awk 循环

awk支持for循环,常与数组结合使用,实现数组遍历、数据迭代等操作,尤其适合批量处理数组中的统计数据。

循环与数组结合的生产案例

示例:初始化数组a(下标0-2,值分别为10、20、30),通过for循环遍历数组,打印每个下标的“下标-值”对:
[root@localhost ~]# awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print i,a[i]}}'
在这里插入图片描述

生产场景:基于数组与循环的日志统计

场景1:统计httpd访问日志中客户端IP的出现次数

通过数组存储IP(下标为IP地址),每遇到一个IP就使对应数组值+1(计数),最后用for循环遍历数组输出统计结果,命令如下:
[root@localhost ~]# awk '{a[$1]+=1;} END {for(i in a){print a[i]" "i;}}' /var/log/httpd/access_log | sort -r
[root@localhost ~]# awk '{ip[$1]++;}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log | sort -r
原理:数组ip的下标为日志第一列(客户端IP),ip[$1]++实现IP出现次数累加;END模块中for循环遍历数组,sort -r按次数倒序排列结果。

场景2:统计/var/log/secure中失败登录的IP及次数

筛选日志中包含“Failed password”(失败登录)的行,用数组ip存储IP(下标为日志第11列,即客户端IP)并计数,最后遍历数组输出,命令如下:
[root@localhost ~]# awk '/Failed password/{ip[$11]++}END{for(i in ip){print i","ip[i]}}' /var/log/secure

5.4 生产脚本编写:数组与逻辑控制结合

基于数组统计的结果,结合shell的if逻辑和循环,可编写自动化脚本实现告警等功能。例如,筛选/var/log/secure中失败登录次数≥3次的IP并提示告警,脚本内容如下:

#!/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统计失败登录IP及次数(结果格式为“IP,次数”),再通过shell循环拆分IP和次数,若次数≥3则打印告警信息。
拓展:当一个ip三次登录失败时禁止其继续连接。

iptables -A INPUT -p tcp --dport 22 -s $ip  -j DROP

六、awk vs grep vs sed:该用谁?

很多人分不清这三个工具,最后总结一张表,帮你快速选择:

工具核心能力适用场景一句话总结
grep文本搜索与匹配单纯查找关键词、过滤行“找东西”
sed流式编辑(整行处理)替换文本、删除行、插入行“改东西”
awk字段处理、统计与格式化提取列、计算数据、生成报告“拆字段、算数据”

七、学习建议

awk的语法灵活,光看理论不够,建议:

  1. 先练基础案例:用/etc/passwd/var/log/messages等系统文件练手,熟悉内置变量;
  2. 再做实战场景:尝试统计自己项目的日志(如用户访问次数、错误码统计);
  3. 复杂逻辑写脚本:当命令行逻辑过长时,用-f脚本文件,方便维护。

掌握awk后,你会发现以前需要写几行Python的文本处理需求,用一行awk就能搞定——这就是Linux命令行的效率之美!

需要我帮你把某类awk案例(比如日志统计、系统监控)整理成可直接复用的脚本吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95641.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95641.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

毕业项目推荐:68-基于yolov8/yolov5/yolo11的水稻虫害检测识别系统(Python+卷积神经网络)

文章目录 项目介绍大全&#xff08;可点击查看&#xff0c;不定时更新中&#xff09;概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式…

Qt为什么要引入QML语言?

Qt发布于1991年&#xff0c;经过30多年的发展&#xff0c;Qt/C已经成为了众多学子&#xff0c;拿来学习C的首选框架。Qt/Widgets&#xff0c;相对于其他界面库&#xff08;如GNOME、KDE&#xff09;&#xff0c;其实已经很优秀&#xff0c;已经可以成为number one了。在已经是第…

设计模式在Java中的应用:从单例模式到工厂模式的全面解析!

全文目录&#xff1a;开篇语前言1. 单例模式&#xff1a;确保全局只有一个实例1.1 饿汉式单例1.2 懒汉式单例1.3 双重检查锁定&#xff08;DCL&#xff09;2. 工厂模式&#xff1a;简化对象创建2.1 简单工厂模式2.2 工厂方法模式2.3 抽象工厂模式3. 其他设计模式3.1 观察者模式…

Meta AIUCSD放大招:DeepConf 让大语言模型推理既快又准,84.7%的token节省+近乎完美的准确率!

1. 【前言】 Meta&UCSD 大语言模型&#xff08;LLMs&#xff09; 在推理任务中通过自一致性等测试时缩放方法展现出巨大潜力&#xff0c;但存在精度收益递减和计算开销高的问题。为此&#xff0c;Meta与UCSD的研究人员提出DeepConf方法&#xff0c;它利用模型内部的置信度信…

解决leetcode第3671.子序列美丽值求和问题

3671. 子序列美丽值求和难度&#xff1a;困难问题描述&#xff1a;给你一个长度为 n 的整数数组 nums。对于每个 正整数 g&#xff0c;定义 g 的 美丽值 为 g 与 nums 中符合要求的子序列数量的乘积&#xff0c;子序列需要 严格递增 且最大公约数&#xff08;GCD&#xff09;恰…

电机控制(一)-电机分类

电机分类 电机分类&#xff1a; 电机的拓扑模型并没有发生太大变化,变化较大的是控制电机的方法。 常见的电机类型有&#xff1a; 步进电机vs伺服电机 在工业自动化、机器人、精密设备等领域&#xff0c;步进电机和伺服电机是两种最常用的驱动电机&#xff0c;但两者的核心…

【Qt】QToolBar、QToolButton的常用用法

一、QToolBar 常用用法 QToolBar 是 Qt 中用于创建工具栏的控件&#xff0c;可快速放置常用功能按钮、分隔符或自定义控件&#xff0c;并支持拖动停靠、浮动等特性。 1. 基础创建与添加到主窗口 // 在 QMainWindow 中创建工具栏 QToolBar *toolBar new QToolBar(tr("主工…

DVWA靶场通关笔记-验证码绕过Insecure CAPTCHA (Impossible级别)

目录 一、reCAPTCHA 1、配置security为Impossible级别。 2、配置RECAPTCHA参数 3、再次打开靶场 二、源码分析 1、index.php 2、impossible.php 3、功能函数 三、reCAPTCHA 防范分析 1、严格的参数验证与处理 2、预处理防止SQL注入 3、CAPTCHA 验证通过 4、验证当前…

MySQL安装(如果之前有安装过MySQL,先执行下面的卸载流程)

1.安装MySQL 1.1更新系统的软件包列表 sudo apt-get update1.2安装MySQL服务器 sudo apt-get install mysql-server1.3检查MySQL服务是否启动&#xff0c;若没有启动手动启动若没有启动执行&#xff1a; sudo service mysql start1.4登录MySQL&#xff08;默认安装之后不需要密…

Streamlit 数据看板模板:非前端选手快速搭建 Python 数据可视化交互看板的实用工具

你想想看&#xff0c;平时你用 Python 跑出来一堆数据 —— 比如用户留存率、产品销量变化&#xff0c;想给领导或者同事看&#xff0c;总不能直接发个 CSV 文件或者一堆静态图吧&#xff1f;对方看的时候还得自己翻数据&#xff0c;想对比下上个月和这个月的变化都费劲&#x…

FMC、FMC+ 详解

文章目录FMC 简介FMC 引脚输出定义High-pin count (HPC) connector, HPC pinoutLow-pin count (LPC) connector, LPC pinoutPin and signal descriptionFMC 简介VITA57 标准更新历史VITA57.4 标准推出的原因FMC 引脚输出定义Altera 开发板的 FMC 引脚定义英特尔 Arria 10 GX FP…

小迪web自用笔记24

黑名单机制。如果被过滤可以试试PHP5看看过滤没&#xff08;或者其他变种变形&#xff09;&#xff0c;但是得看环境有些环境会被当成下载&#xff0c;有些会直接打开。白名单机制只允许这几个特定后缀可以上传&#xff0c;比黑名单更安全。直接从信息图中获取文件类型。文件类…

私有部署问卷系统、考试系统、投票系统、测评系统的最佳选择-调问开源问卷表单(DWSurvey)

在选择私有部署问卷系统的时候&#xff0c;调问问卷系统(DWSurvey)是一定要尝试一下&#xff0c;而且可以应用到私有部署考试系统、私有部署投票系统、私有部署测评系统等多个应用场景。 私有部署问卷、考试、测评、投票系统的优势不言而喻&#xff0c;就拿私有部署考试系统来说…

企业实用——MySQL的备份详解

序言: 本次基于mysql8.0.40来给大家做数据库的备份的实用技巧和思路!对于mysql基础的部分后续我会节选部分给大家讲解,本篇文章适合有一定数据库基础的小伙伴看。 目录 一、MySQL备份概述 1、关于数据保存你要知道 2、到底要备份什么 备份什么 MySQL体系结构(MySQL =…

使用 FunASR 工具包实现音频文件的语音识别

使用 FunASR 工具包实现音频文件的语音识别&#xff0c;并将识别结果保存为文本文件&#xff0c;支持单文件处理和批量处理。电脑环境需要配置&#xff0c;我使用的PyTorch版本: 2.4.1cu121&#xff0c;CUDA可用: True。FunASR 是一个功能强大、性能卓越、面向工业应用的语音识…

【STM32】定时器编码器接口

【STM32】定时器编码器接口一、编码器接口1.1 正交编码器1.2 编码器接口基本结构1.3 工作模式二、编码器接口测速一、编码器接口 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT的自增或…

浪潮科技Java开发面试题及参考答案(120道题-中)

请介绍一下 SpringMVC 的运行流程&#xff1f;从用户发送请求到响应返回的完整步骤是什么&#xff1f;SpringMVC 是基于MVC架构的Web框架&#xff0c;其运行流程围绕“前端控制器&#xff08;DispatcherServlet&#xff09;”展开&#xff0c;通过多个组件协同工作&#xff0c;…

k8s初始化常见问题

执行初始化&#xff1a;kubeadm init --apiserver-advertise-address192.168.88.110 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr10.244.0.0/16 --control-plane-endpointweb01报错信息&#xff1a;age-repository registry.aliyuncs.com/…

Python学习笔记--使用Django修改和删除数据

一、修改方式一&#xff1a;模型类的对象.属性 更改的属性值&#xff0c;模型类的对象.save()返回值&#xff1a;编辑的模型类的对象。def update_book(request):book models.Book.objects.filter(pk1).first()book.price "169"book.save()return HttpResponse(bo…

如何评价2025年数学建模国赛?

2025年全国大学生数学建模竞赛将于9月4日正式举行&#xff01; 有些第一次参加数学竞赛的同学可能觉得自己还没准备好&#xff0c;临近比赛感到紧张很正常&#xff0c;但需调整心态——数学建模比赛本就是学习过程&#xff0c;遇到不会的知识及时搜索、现学现用即可&#xff0…