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

AWK命令完全指南:从理论到实战的文本处理利器

AWK命令完全指南:从理论到实战的文本处理利器

文章目录

  • AWK命令完全指南:从理论到实战的文本处理利器
    • 一、AWK概述:起源与版本
      • 1.1 常见版本
    • 二、AWK工作原理与流程
      • 2.1 核心工作原理
      • 2.2 完整工作流程:BEGIN → 主体 → END
    • 三、AWK基础语法:选项与内置变量
      • 3.1 常用命令选项
      • 3.2 核心内置变量
    • 四、AWK实战案例:从基础到进阶
      • 4.1 基础操作:字段提取与输出
        • 案例1:提取`/etc/passwd`中的用户名和家目录
        • 案例2:打印指定行的内容
        • 案例3:打印最后一列和总行数
      • 4.2 模式匹配:按内容过滤行
        • 案例4:过滤包含“root”的行
        • 案例5:按数值条件过滤(如UID判断)
      • 4.3 内置变量进阶:FS、OFS、FNR的使用
        • 案例6:自定义输入/输出分隔符
        • 案例7:处理多个文件时保持独立行号
      • 4.4 数值运算与统计
        • 案例8:计算1-10的和
        • 案例9:统计系统用户和普通用户数量
      • 4.5 条件判断:if语句的使用
        • 案例10:按UID分类输出用户
      • 4.6 生产环境实战:提取系统信息
        • 案例11:提取网卡IP地址
        • 案例12:提取根分区可用空间
    • 五、AWK高级技巧:脚本与函数
      • 5.1 编写AWK脚本:统计日志中不同状态码的数量
    • 六、AWK与其他工具的结合
        • 案例13:提取内存使用情况并排序
    • 七、总结

在Linux/Unix系统的文本处理工具中,AWK绝对是“瑞士军刀”般的存在。它不仅是一个命令行工具,更是一门专门为文本分析设计的编程语言,擅长扫描、过滤、统计和格式化文本数据。本文将从AWK的基础理论出发,结合大量实战案例,带你全面掌握这一强大工具。

一、AWK概述:起源与版本

AWK诞生于20世纪70年代的贝尔实验室,其命名源自三位创始人Alfred AhoPeter WeinbergerBrian Kernighan的姓氏首字母。作为行处理工具,它能从标准输入、管道或文件中读取数据,按规则进行处理后输出结果。

1.1 常见版本

目前Linux系统中最常用的是GNU AWK(简称gawk),各大发行版(如CentOS、Ubuntu)均默认预装,且与原始AWK、New AWK(nawk)完全兼容。可以通过以下命令验证:

# 查看awk的实际指向
ll `which awk`
# 输出示例:lrwxrwxrwx. 1 root root 4 8月 19 2022 /usr/bin/awk -> gawk

二、AWK工作原理与流程

AWK的核心优势在于**“分字段处理”** —— 与sed侧重整行处理不同,AWK会先将每行文本按分隔符拆分为“字段”,再按规则处理指定字段。

2.1 核心工作原理

  1. 逐行读取:从输入源(文件/管道/标准输入)逐行读取文本,存入内存;
  2. 字段拆分:默认以空格或Tab为分隔符,将当前行拆分为多个字段,用$1(第1列)、$2(第2列)…$NF(最后一列)表示,$0代表整行;
  3. 规则匹配:根据用户定义的“模式(Pattern)”判断是否处理当前行;
  4. 执行动作:若匹配成功,执行对应的“动作(Action)”;
  5. 循环重复:重复步骤1-4,直到所有行处理完毕。

2.2 完整工作流程:BEGIN → 主体 → END

AWK脚本由开始块(BEGIN)主体块(Body)结束块(END) 三部分组成,执行顺序严格固定:

模块执行时机作用必须大写?
BEGIN块读取输入数据前仅执行一次初始化变量、打印表头
主体块每读一行数据执行一次核心处理逻辑(模式+动作)无关键字
END块所有数据处理完仅执行一次汇总结果(如统计行数、求和)

语法结构

awk [选项] 'BEGIN{ 初始化命令 }模式{ 处理动作 }END{ 汇总命令 }
' 输入文件

三、AWK基础语法:选项与内置变量

掌握选项和内置变量是使用AWK的基础,它们能极大简化文本处理逻辑。

3.1 常用命令选项

选项说明示例
-F指定输入字段分隔符(替代默认空格/Tab)awk -F: '{print $1}' /etc/passwd
-f从脚本文件中读取AWK命令(适合复杂逻辑)awk -f script.awk data.txt
-v定义自定义变量并赋值awk -v num=10 '{print $1+num}' data.txt

3.2 核心内置变量

AWK预定义了一系列变量,无需声明即可直接使用,最常用的如下:

变量名说明示例场景
$0当前处理的整行文本打印整行:awk '{print $0}' data.txt
$n当前行的第n个字段(n为正整数)打印第2列:awk '{print $2}' data.txt
NF当前行的字段总数(Number of Fields)打印最后一列:awk '{print $NF}' data.txt
NR已处理的总行数(Number of Records)打印行号+内容:awk '{print NR,$0}' data.txt
FNR每个文件独立计数的行号(多文件时用)处理两个文件:awk '{print FNR,$0}' a.txt b.txt
FS输入字段分隔符(同-F选项)BEGIN{FS=":"}{print $1}
OFS输出字段分隔符(默认空格)BEGIN{FS=":";OFS="---"}{print $1,$2}
FILENAME当前处理的文件名awk '{print FILENAME,$1}' data.txt

四、AWK实战案例:从基础到进阶

理论结合实践才是掌握AWK的关键。以下案例基于Linux系统常见文件(如/etc/passwdifconfig输出等),覆盖日常工作中90%的使用场景。

4.1 基础操作:字段提取与输出

案例1:提取/etc/passwd中的用户名和家目录

/etc/passwd以冒号(:)分隔,第1列为用户名,第6列为家目录:

# 用-F指定分隔符,打印第1和第6列
awk -F: '{print $1,"的家目录是:",$6}' /etc/passwd
# 输出示例:root 的家目录是: /root

在这里插入图片描述

案例2:打印指定行的内容
# 打印第3行(NR==3)
awk 'NR==3{print}' /etc/passwd
# 打印第2-5行(NR>=2 && NR<=5)
awk 'NR>=2 && NR<=5{print $1}' /etc/passwd

在这里插入图片描述

案例3:打印最后一列和总行数
# 打印/etc/passwd每行的最后一列($NF)
awk -F: '{print $NF}' /etc/passwd
# 用END块统计总行数
awk 'END{print "总行数:",NR}' /etc/passwd

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

4.2 模式匹配:按内容过滤行

AWK支持正则表达式匹配关系运算匹配,用~表示“包含”,!~表示“不包含”。

案例4:过滤包含“root”的行
# 打印包含root的整行
awk '/root/' /etc/passwd
# 打印用户名(第1列)包含“ro”的行
awk -F: '$1~/ro/{print $1,$7}' /etc/passwd
# 打印shell(第7列)不是nologin的用户名
awk -F: '$7!~/nologin$/{print $1,"的shell是:",$7}' /etc/passwd

在这里插入图片描述

案例5:按数值条件过滤(如UID判断)

/etc/passwd第3列为UID,过滤UID<10的系统用户:

# UID<10的用户($3<10)
awk -F: '$3<10{print $1,"的UID是:",$3}' /etc/passwd
# 输出示例:root 的UID是: 0

在这里插入图片描述

4.3 内置变量进阶:FS、OFS、FNR的使用

案例6:自定义输入/输出分隔符
# 输入用:分隔,输出用“|”分隔
awk 'BEGIN{FS=":";OFS="|"}{print $1,$3,$7}' /etc/passwd
# 输出示例:root|0|/bin/bash

在这里插入图片描述

案例7:处理多个文件时保持独立行号

当处理多个文件时,NR会累计行数,FNR会为每个文件重新计数:

# 同时处理/etc/passwd和/etc/hosts,打印行号和内容
awk '{print "文件"FILENAME"的第"FNR"行:",$0}' /etc/passwd /etc/hosts

在这里插入图片描述

4.4 数值运算与统计

AWK支持常见的数学运算(+、-、*、/、%、^),可在BEGIN块初始化变量,在主体块累计计算。

案例8:计算1-10的和
awk 'BEGIN{sum=0;for(i=1;i<=10;i++)sum+=i;print "1-10的和:",sum}'
# 输出:1-10的和: 55

在这里插入图片描述

案例9:统计系统用户和普通用户数量

UID<1000为系统用户,UID>=1000为普通用户:

awk -F: 'BEGIN{sys=0;normal=0}  # 初始化计数器$3<1000{sys++}         # 系统用户计数$3>=1000{normal++}     # 普通用户计数END{print "系统用户数:",sys;"普通用户数:",normal}
' /etc/passwd

在这里插入图片描述

4.5 条件判断:if语句的使用

AWK的if语句支持单分支、双分支(if-else)和多分支(if-else if-else),适合复杂逻辑判断。

案例10:按UID分类输出用户
awk -F: '{if($3==0){print $1,"是超级用户"}else if($3<1000){print $1,"是系统用户"}else{print $1,"是普通用户"}
}' /etc/passwd

在这里插入图片描述

4.6 生产环境实战:提取系统信息

案例11:提取网卡IP地址
# 过滤包含netmask的行,打印第2列(IP地址)
ifconfig ens33 | awk '/netmask/{print "本机IP:",$2}'
# 输出示例:本机IP: 192.168.1.100

在这里插入图片描述

案例12:提取根分区可用空间
# df -h的第2行为根分区,第4列为可用空间
df -h | awk 'NR==2{print "根分区可用空间:",$4}'
# 输出示例:根分区可用空间: 45G

在这里插入图片描述

五、AWK高级技巧:脚本与函数

对于复杂逻辑,可将AWK命令写入脚本文件(.awk),再用-f选项执行。

5.1 编写AWK脚本:统计日志中不同状态码的数量

假设有nginx访问日志access.log,格式如下:

192.168.1.1 - - [01/Jan/2024:12:00:00 +0800] "GET /index.html HTTP/1.1" 200 1024
192.168.1.2 - - [01/Jan/2024:12:01:00 +0800] "POST /login HTTP/1.1" 404 512

创建脚本count_status.awk

# 初始化数组(关联数组,键为状态码,值为次数)
BEGIN{print "=== 日志状态码统计 ==="}
# 第9列为状态码,累计计数
{status[$9]++}
# 结束时打印结果
END{for(code in status){print "状态码"code":"status[code]"次"}
}

执行脚本:

awk -f count_status.awk access.log
# 输出示例:
# === 日志状态码统计 ===
# 状态码200:1次
# 状态码404:1次

六、AWK与其他工具的结合

AWK常与grepsedsort等工具配合,形成强大的文本处理流水线。

案例13:提取内存使用情况并排序
# 用free命令获取内存,awk提取第2列(总量、已用、空闲),sort排序
free -m | awk 'NR==2{print "总内存:"$2"MB";print "已用内存:"$3"MB";print "空闲内存:"$4"MB"}' | sort -n -k2

在这里插入图片描述

七、总结

AWK作为一款“文本处理编程语言”,其核心价值在于**“按字段处理+规则驱动”**。掌握它的关键在于:

  1. 理解BEGIN→主体→END的执行流程;
  2. 熟练使用内置变量(尤其是$0$nNFNR);
  3. 灵活结合正则匹配、条件判断和数值运算;
  4. 复杂逻辑用脚本文件管理,提高可维护性。

从简单的字段提取到复杂的日志统计,AWK都能胜任。多加练习,你会发现它能极大提升Linux文本处理的效率。

http://www.xdnf.cn/news/1447579.html

相关文章:

  • Spring Boot + Nacos 配置中心示例工程
  • tcpdump用法
  • Best Video网页官网入口 – 免费在线网页视频解析下载器
  • 认识HTML
  • 用资产驱动方法构建汽车网络安全档案
  • VPS云服务器安全加固指南:从入门到精通的全面防护策略
  • TypeScript 内置工具类型大全(ReturnType、Omit、Pick 等)
  • 【Unity项目经验分享】实现左右分屏裸眼3D程序
  • 数据结构之加餐篇 -顺序表和链表加餐
  • 从 0 到 1 实现 PyTorch 食物图像分类:核心知识点与完整实
  • 基础看门狗--idf开发esp32s3
  • PNP具身解读——RSS2025论文加州伯克利RLDG: 通过强化学习实现机器人通才策略提炼。
  • 基于物联网的智慧用电云平台构建与火灾防控应用研究
  • 复杂网络环境不用愁,声网IoT多通道传输实战经验丰富
  • Coze使用教程-插件
  • 袋鼠云产品功能更新报告14期|实时开发,效率再升级!
  • Kafka面试精讲 Day 6:Kafka日志存储结构与索引机制
  • 浏览器插件开发--通过调用本地nmap实现nmap插件扫描
  • python如何解决html格式不规范问题
  • Android使用内存压力测试工具 StressAppTest
  • [嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_用Qt编译linux-Opencv库 测试
  • 显存与内存
  • 【甲烷数据】MethaneSAT 卫星遥感数据
  • 使用DCGAN实现动漫图像生成
  • 树莓集团产教融合:数字学院践行职业教育“实体化运营”要求
  • Ubuntu 系统 LVM 逻辑卷扩容教程
  • 中小企业 AI 转型难?成本、技术、人才三重困境下,轻量化解决方案来了
  • 单位冲击响应频谱
  • python-对图片中的头像进行抠图
  • 确定软件需求的方法