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

Linux awk 命令完全指南:从基础语法到运维实战

Linux awk 命令完全指南:从基础语法到运维实战

在 Linux 文本处理三剑客(grepsedawk)中,awk 以其强大的字段级处理能力和灵活的格式化输出功能成为运维工程师的“瑞士军刀”。它不仅能按行解析文本,更能精准分割字段、实现复杂逻辑判断,尤其适合日志分析、数据统计、配置解析等场景。本文基于 CentOS 7(GNU awk 4.0.2) 环境,从基础语法到企业级实战,系统讲解 awk 的核心用法,所有命令均经过验证可直接复现。

一、awk 是什么?定位与核心能力

awk 诞生于 1977 年,得名于三位开发者(Aho、Weinberger、Kernighan)的首字母,本质是一种模式驱动的解释型编程语言,核心定位可概括为:
“按行读取文本 → 按字段分割数据 → 按模式匹配筛选 → 按需求格式化输出”

1.1 三剑客功能对比(精准定位)

工具核心优势适用场景典型需求示例
grep快速查找/过滤文本按关键字匹配行、提取片段筛选日志中的 ERROR 信息、过滤特定 IP
sed批量编辑文本(替换/删除)按模式修改行内容、删除空行/注释替换配置文件中的域名、清理日志注释
awk字段级处理、数据统计解析结构化数据、格式化输出、统计提取 /etc/passwd 用户信息、统计访问 Top10 IP

1.2 学会 awk 能解决哪些问题?

  • 结构化数据解析:处理 CSV、/etc/passwd、Nginx 日志等格式固定的数据;
  • 精准字段提取:按列号/分隔符提取目标数据(如从日志中提取 IP、URL、状态码);
  • 条件逻辑判断:筛选符合条件的行(如 UID>1000 的普通用户、状态码为 5xx 的错误请求);
  • 数据统计分析:统计单词频率、IP 访问次数、文件行数等;
  • 格式化输出:自定义表头、字段分隔符,让输出更易读(如给数据加备注、对齐列)。

二、awk 基础:语法与核心概念

2.1 基本语法格式

awk 的语法由「模式(Pattern)」和「动作(Action)」组成,核心结构如下:

awk [选项] '模式{动作}' 数据来源
组成部分说明示例
选项常用 -F 分隔符(指定字段分隔符)、-v 变量=值(定义自定义变量)awk -F: '{...}' /etc/passwd
模式筛选条件(如行号、正则、范围),不写模式则默认处理所有行NR==3(第3行)、/root/(含root的行)
动作处理逻辑(如 print 输出、变量计算),必须用 {} 包裹,多语句用 ; 分隔{print $1,$3}(输出第1、3列)
数据来源可直接跟文件名,或通过管道传递(`)、标准输入(stdin`)

2.2 核心概念:行(Record)与字段(Field)

awk 处理文本时,默认按“行-字段”二级结构解析数据,理解这两个概念是学好 awk 的关键:

概念定义控制变量引用方式
行(Record)每一行文本视为一条“记录”,行与行的分隔符默认是 \n(换行符)RS(行分隔符)$0(当前行完整数据)
字段(Field)每一行按“字段分隔符”分割为多个“字段”(列),默认分隔符是空格/制表符FS(字段分隔符)$N(第N列,如 $1、$2)
示例:解析一行文本

假设文本行:zack linux python music,其“行-字段”结构如下:

概念对应值变量/语法
行(Record)zack linux python music$0
字段数4NF(内置变量)
第1字段zack$1
第4字段music$4
最后1字段music$NF
倒数第2字段python$(NF-1)

三、awk 核心内置变量(必背)

awk 预定义了大量内置变量,用于控制解析规则和获取数据元信息,常用变量如下(按功能分类):

3.1 行与字段相关变量

变量含义示例(解析 zack linux python music
NR当前处理的全局行号(多文件累计)处理第1行时,NR=1
FNR当前文件的行号(多文件独立计数)处理第二个文件第3行时,FNR=3
NF当前行的字段总数(列数)该行有4列,NF=4
$N第N个字段(N为正整数)$1=zack$4=music
$0当前行的完整数据$0=zack linux python music
$NF当前行的最后一个字段$NF=music

3.2 分隔符相关变量

变量含义默认值示例(自定义)
FS输入字段分隔符(拆分列)空格/制表符FS=":"(按冒号拆分,解析 /etc/passwd
OFS输出字段分隔符(拼接列)空格OFS="---"(输出用 --- 分隔列)
RS输入行分隔符(拆分行)\n(换行)RS=" "(按空格拆分,单词当行)
ORS输出行分隔符(拼接行)\n(换行)ORS="@@"(输出行用 @@ 结尾)

3.3 其他常用变量

变量含义示例
FILENAME当前处理的文件名处理 /etc/passwd 时,FILENAME=/etc/passwd
ARGC命令行参数的总数awk ... file1 file2 中,ARGC=3
ARGV命令行参数的数组(从0开始)ARGV[0] = "awk"ARGV[1] = "file1"

示例:内置变量实战

步骤1:创建测试文件 zack.log
# 生成10行数据,每行5个以空格分隔的字段(zack01~zack50)
echo zack{01..50} | xargs -n 5 > zack.log
步骤2:用内置变量解析数据
  1. 显示行号+字段数+完整行

    awk '{print "行号:"NR, "字段数:"NF, "内容:"$0}' zack.log
    

    执行效果

    行号:1 字段数:5 内容:zack01 zack02 zack03 zack04 zack05
    行号:2 字段数:5 内容:zack06 zack07 zack08 zack09 zack10
    行号:3 字段数:5 内容:zack11 zack12 zack13 zack14 zack15
    
  2. 提取第2行的第1列和最后1列

    awk 'NR==2{print "第2行第1列:"$1, "第2行最后1列:"$NF}' zack.log
    

    执行效果

    第2行第1列:zack06 第2行最后1列:zack10
    

四、awk 模式:如何精准匹配目标行?

awk 的“模式”是筛选行的核心,支持 4 种核心模式,以及特殊模式 BEGIN/END,覆盖绝大多数场景。

4.1 行号模式:按行号筛选

通过 NR(行号变量)指定具体行,支持“等于、范围、列表”三种用法:

模式语法含义示例命令(基于 zack.log
NR==N仅处理第N行awk 'NR==3{print $0}' zack.log(输出第3行)
NR>=N && NR<=M处理第N到M行(含边界)awk 'NR>=2&&NR<=4{print $1,$3}' zack.log(2-4行的1、3列)
`NR~/(NMK)/`

4.2 正则模式:按内容筛选

/正则表达式/ 匹配行内容,支持基础正则(如 ^ 行首、$ 行尾、. 任意字符):

需求正则模式示例命令(解析 /etc/passwd
匹配 root 用户行/^root/awk -F: '/^root/{print $1,$NF}' /etc/passwd(输出root的Shell)
匹配允许登录的用户/bash$/awk -F: '/bash$/{print $1}' /etc/passwd(Shell为bash的用户)
匹配用户名含 zack 的行/zack/awk -F: '/zack/{print $1,$6}' /etc/passwd(输出zack的家目录)
排除注释行(#开头)!/^#/awk '!/^#/{print $0}' /etc/nginx/nginx.conf(过滤注释)

4.3 比较模式:按字段/数值筛选

支持数值比较==><!=>=<=)和字符串匹配~!~):

需求比较模式示例命令(解析 /etc/passwd
筛选 UID=0 的用户$3==0awk -F: '$3==0{print $1,"UID="$3}' /etc/passwd
筛选 UID>1000 的普通用户$3>1000awk -F: '$3>1000{print $1,"普通用户"}' /etc/passwd
筛选 Shell 不是 nologin 的$NF!~/nologin/awk -F: '$NF!~/nologin/{print $1,"可登录"}' /etc/passwd
筛选家目录含 /home 的用户$6~/\/home/(/需转义)awk -F: '$6~/\/home/{print $1,$6}' /etc/passwd

4.4 范围模式:按起始/结束条件筛选

模式1,模式2 匹配“从模式1到模式2”的所有行(包含边界行),适合批量筛选连续行:

# 示例:匹配从root行到daemon行的所有用户(含root和daemon)
awk -F: '/^root/,/^daemon/{print NR,$1}' /etc/passwd

执行效果

1 root
2 bin
3 daemon

注意:范围模式是“非贪婪”的,找到第一个匹配模式2的行后,就停止当前范围的匹配。

4.5 特殊模式:BEGINEND

  • BEGIN:在 awk 读取文本之前执行,仅执行1次,常用于初始化变量、打印表头;
  • END:在 awk 读取所有文本之后执行,仅执行1次,常用于统计结果、打印总结。
示例:格式化输出 /etc/passwd 前5个用户
awk -F: '
# BEGIN:读取文件前执行(初始化变量、打印表头)
BEGIN{OFS="---"  # 输出字段分隔符设为---print "行号---用户名---UID---家目录---登录Shell"  # 表头
}
# 模式+动作:处理前5行
NR<=5{print NR,$1,$3,$6,$NF  # 输出行号、用户名、UID、家目录、Shell
}
# END:读取文件后执行(总结)
END{print "共处理"NR"行数据,已输出前5行"
}' /etc/passwd

执行效果

行号---用户名---UID---家目录---登录Shell
1---root---0---/root---/bin/bash
2---bin---1---/bin---/sbin/nologin
3---daemon---2---/sbin---/sbin/nologin
4---adm---3---/var/adm---/sbin/nologin
5---lp---4---/var/spool/lpd---/sbin/nologin
共处理45行数据,已输出前5行

五、awk 字段处理:自定义分隔符

默认情况下,awk 按“空格/制表符”分割字段,但实际场景中数据常以冒号(/etc/passwd)、逗号(CSV)、@(邮箱)等分隔,需自定义 FS(输入字段分隔符)。

5.1 指定分隔符的 3 种方式

方式语法格式示例(解析 zack:linux:python:music
选项 -Fawk -F 分隔符 '{...}'awk -F: '{print $1,$3}'zack python
变量 -v FS=分隔符awk -v FS=分隔符 '{...}'awk -v FS=: '{print $2,$4}'linux music
BEGIN 中定义awk 'BEGIN{FS=分隔符}{...}'awk 'BEGIN{FS=:}{print $1,$4}'zack music

推荐用法:简单分隔符用 -F(如 -F:),复杂分隔符(含正则)在 BEGIN 中定义。

5.2 高级分隔符:多字符/正则分隔

awk 支持用正则表达式作为分隔符,解决“多字符分隔”“不确定分隔符”等复杂场景:

需求分隔符设置示例命令(解析 zack@linux#python-music
按 @/😕#/- 任意一个分隔FS="[#@:-]"awk -v FS="[#@:-]" '{print $1,$2,$3,$4}'zack linux python music
按多个连续空格分隔FS="[ ]+"awk -v FS="[ ]+" '{print $1,$2}'(处理 zack linux) → zack linux
[] 分隔`FS="\[\]"`(需转义)

示例:解析 CSV 文件

假设有 user.csv 文件(内容:用户名,密码,身份证号):

zack1,123456,110101199001011234
zack2,654321,310101199505056789
zack3,abcdef,440101200010101357

需求:提取“用户名+身份证号”,用 --- 分隔输出,并添加表头:

awk -v FS=',' -v OFS='---' '
BEGIN{print "用户名---身份证号"}  # 表头
{print $1,$3}  # 输出第1列(用户名)和第3列(身份证号)
' user.csv

执行效果

用户名---身份证号
zack1---110101199001011234
zack2---310101199505056789
zack3---440101200010101357

六、awk 运维实战场景(企业级)

6.1 场景1:统计 Nginx 访问日志中访问量 Top5 的 IP

日志格式(/var/log/nginx/access.log):
192.168.1.100 - - [15/Oct/2024:10:00:00 +0800] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [15/Oct/2024:10:01:00 +0800] "GET /login.html HTTP/1.1" 200 5678
192.168.1.100 - - [15/Oct/2024:10:02:00 +0800] "POST /submit HTTP/1.1" 200 9012

命令

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -5

解析

  1. awk '{print $1}':提取日志第1列(客户端 IP);
  2. sort:按 IP 排序(为 uniq 去重做准备);
  3. uniq -c:统计每个 IP 的重复次数(-c 表示“计数”);
  4. sort -nr:按计数倒序-n 数值排序,-r 倒序);
  5. head -5:取前 5 个 IP。

执行效果

  120 192.168.1.10089 192.168.1.10156 192.168.1.10232 192.168.1.10328 192.168.1.104

6.2 场景2:提取网卡 IP 地址(排除 127.0.0.1)

命令

ip addr show | awk '/inet / && !/127.0.0.1/{gsub(/\/.*/,"",$2);print "网卡"$NF"的IP:"$2}'

解析

  1. ip addr show:获取所有网卡的网络信息;
  2. /inet / && !/127.0.0.1/:匹配含 inet (IP 行)且不含 127.0.0.1(本地回环)的行;
  3. gsub(/\/.*/,"",$2):删除 $2(IP 字段)中的 / 及后面内容(如 192.168.1.100/24192.168.1.100);
  4. print "网卡"$NF"的IP:"$2:输出网卡名($NF,如 ens33)和 IP($2)。

执行效果

网卡ens33的IP:192.168.1.100
网卡docker0的IP:172.17.0.1

6.3 场景3:判断 22(SSH)和 80(HTTP)端口是否存活

命令

netstat -tuln | awk '
BEGIN{print "端口状态检测结果:\n端口\t状态"}  # 表头
$4~/:22$/{port22="已开启"}  # 匹配22端口
$4~/:80$/{port80="已开启"}  # 匹配80端口
END{# 三元运算符:变量存在则输出“已开启”,否则“未开启”print "22\t"(port22?port22:"未开启")print "80\t"(port80?port80:"未开启")
}'

执行效果

端口状态检测结果:
端口        状态
22        已开启
80        未开启

6.4 场景4:统计文本中单词出现频率 Top5

假设有 english.log 文件(内容:I like zack, zack likes linux, linux is good):

命令

awk -v RS='[^a-zA-Z]+' '{if($0!="")count[$0]++}END{for(word in count)print count[word],word}' english.log | sort -nr | head -5

解析

  1. RS='[^a-zA-Z]+':按“非字母”分割行(每个单词视为一条独立行);
  2. if($0!="")count[$0]++:非空单词计入 count 数组(key=单词value=出现次数);
  3. for(word in count)print count[word],word:遍历数组,输出次数和单词;
  4. sort -nr | head -5:按次数倒序,取 Top5。

执行效果

2 zack
2 linux
1 I
1 like
1 likes

七、awk 常见问题与避坑指南

7.1 问题1:字段分隔符设置不生效?

原因1:分隔符含特殊字符未转义

awk 中 |[\ 等是特殊字符,需用 \ 转义,或放在 [] 中:

  • 错误:awk -F| '{...}'| 被解析为“或”);
  • 正确:awk -F'|' '{...}'awk -F\\| '{...}'
原因2:同时用 -FBEGIN{FS=} 定义分隔符

-F 优先级高于 BEGIN{FS=},会覆盖后者,建议统一用一种方式:

  • 推荐:简单分隔符用 -F,复杂分隔符用 BEGIN{FS=}

7.2 问题2:print 输出时字段间分隔符不对?

解决方案:设置 OFS(输出字段分隔符)

默认 OFS 是空格,若需自定义(如 ---,),需显式设置:

# 示例:输出用 --- 分隔字段
awk -F: -v OFS='---' '{print $1,$3,$NF}' /etc/passwd

7.3 问题3:处理多文件时行号混乱?

原因:NR 是全局行号,多文件会累计
解决方案:用 FNR 代替 NR(单个文件独立行号)
# 示例:分别显示 file1 和 file2 的前2行(每行标注文件名和行号)
awk 'FNR<=2{print FILENAME"第"FNR"行:"$0}' file1 file2

7.4 问题4:处理中文字符时乱码或匹配失败?

解决方案:设置字符集为 LC_ALL=C

中文字符会影响字段分割和正则匹配,执行前先设置环境变量:

export LC_ALL=C  # 临时生效,永久生效需添加到 ~/.bashrc

八、awk 练习题(含答案)

8.1 基础题:字段提取与格式化

  1. 需求:解析 echo "zack linux python music",输出“姓名:zack,爱好:linux python music”;
    答案

    echo "zack linux python music" | awk '{print "姓名:"$1",爱好:"$2,$3,$4}'
    
  2. 需求:解析 /etc/passwd,输出前3个用户的“用户名-UID-家目录”(用 - 分隔);
    答案

    awk -F: -v OFS='-' 'NR<=3{print $1,$3,$6}' /etc/passwd
    

8.2 进阶题:复杂分隔与条件筛选

  1. 需求:解析 echo "zack:://---linux:..python",提取为 zack linux python
    答案

    echo "zack:://---linux:..python" | awk -v FS='[^a-zA-Z]+' '{print $1,$2,$3}'
    
  2. 需求:筛选 /etc/passwd 中“UID>500 且 Shell 为 /bin/bash”的用户,输出用户名和家目录;
    答案

    awk -F: '$3>500 && $NF=="/bin/bash"{print "用户名:"$1",家目录:"$6}' /etc/passwd
    

九、总结与学习资源

9.1 核心知识点总结

awk 的核心是“行处理 + 字段分割 + 模式匹配 + 格式化输出”,需重点掌握:

  1. 内置变量:NR(行号)、NF(字段数)、$N(字段引用)、FS/OFS(分隔符);
  2. 模式匹配:行号模式(NR==N)、正则模式(/xxx/)、比较模式($3>1000);
  3. 实战场景:日志统计、IP 提取、CSV 解析、端口检测。

9.2 推荐学习资源

  • 官方文档:GNU awk 手册(https://www.gnu.org/software/gawk/manual/);
  • 在线工具:Regex101(https://regex101.com/,测试正则表达式)、AwkFiddle(在线调试 awk 代码);
  • 书籍:《sed与awk(第2版)》、《Linux命令行与Shell脚本编程大全》。

通过本文的学习,可解决 80% 以上的 Linux 文本处理需求。awk 的深度在于其编程语言特性(数组、循环、函数),建议在实战中逐步探索,例如用 awk 编写脚本处理复杂日志分析任务,进一步提升运维效率。

http://www.dtcms.com/a/474889.html

相关文章:

  • 杭州网站关键词推广程序可以做网站吗
  • 教育行业网站设计网站如何验证登陆状态
  • Linux 网络调优之重新认识 Linux 本机网络
  • 万网如何建网站html网站建设实例代码
  • Attention Is All You Need 学习笔记
  • 凡科网站怎样做重庆潼南网站建设
  • Communication Stack简介
  • 多种二分查找
  • 比较好的免费外贸网站东莞皮具网站建设
  • 三好街 做网站丢盖网logo制作免费
  • 储能电池厂追溯升级:电芯卷绕、注液到 Pack 成品的全生命周期数据
  • 茶类网站建设方案四川工程信息网官网
  • 水田智能监控系统
  • 怎么找出网站的备案号阿帕奇网站搭建
  • 网站服务器地址怎么查wordpress 本地 域名绑定
  • 目前网站建设采用什么技术健康咨询类网站模板
  • 普罗米修斯监控实战:从原理到小型项目
  • Ansible-role角色
  • 网站设计 济南中国前500强企业排名
  • 网站开发入门书籍南京网站建设哪家好
  • 解决PyQt5资源模块导入错误:如何修复 ‘No module named ui_sources_rc’ 问题
  • 城市介绍网站模板西充县规划建设局网站
  • 彩票网站开发制作营销类的网站
  • Unity框架YouYouFramework学习第2篇:启动框架
  • wordpress站点赏析检察院网站建设方案
  • wordpress获取时间函数seo在网站制作
  • 计算机视觉(opencv)——基于 MediaPipe 的手势识别系统
  • 免费建网站代码网站登录超时怎么解决
  • 网站开发与管理对应的职业及岗位眉县网站开发
  • 网站建设销售求职东莞建设网住房保障专栏20批公示栏