Shell-AWK详解
目录
一、AWK 核心理论基础
1. 概述与版本
2. 工作原理与流程
3. 基本语法与变量
(1)命令格式
(2)核心内置变量
二、实战案例分类解析
1. 基础字段提取(高频场景)
2. 统计与计算(生产常用)
3. 多文件处理与特殊分隔符
4. 条件判断与逻辑运算
5. 数组与高级统计(生产重点)
6. 调用 Shell 命令与脚本编写
三、关键总结:AWK 与其他工具的分工
一、AWK 核心理论基础
1. 概述与版本
- 本质:文本处理编程语言,行处理工具,擅长扫描、过滤、统计汇总。
- 起源:1970 年代贝尔实验室,得名于创始人
Aho
、Weinberger
、Kernighan
的首字母。 - 版本:
- AWK:原始版本;
- NAWK:AT&T 升级版本;
- GAWK(GNU AWK):Linux 默认版本(CentOS 中
awk
是gawk
的软链接)。
2. 工作原理与流程
- 核心逻辑:逐行读取文本 → 按分隔符拆分字段 → 按「模式(条件)」触发「动作」→ 循环至文件结束。
- 与 sed 的区别:sed 侧重「整行处理」,awk 侧重「字段拆分处理」(将一行拆分为多个字段后操作)。
- 三阶段执行流程:
阶段 作用 执行时机 关键字 BEGIN 块 初始化变量、打印表头 读取文本前,仅执行 1 次 BEGIN
(大写)主体块 按模式匹配行,执行动作(如打印字段) 逐行读取文本时,循环执行 无关键字 END 块 汇总结果(如统计总行数) 读取文本后,仅执行 1 次 END
(大写)
3. 基本语法与变量
(1)命令格式
# 1. 直接执行:选项 + 模式动作 + 目标文件
awk [选项] '模式{动作}' 文件1 文件2...
# 2. 脚本执行:将模式动作写入脚本,通过-f调用
awk -f 脚本文件 文件1 文件2...
- 关键选项:
-F 分隔符
(指定字段分隔符,默认是空格 / 制表符)。
(2)核心内置变量
变量名 | 含义 | 示例 |
---|---|---|
$0 | 当前处理行的整行内容 | awk '{print $0}' zz (打印整行) |
$n | 当前行的第 n 个字段(n 为数字) | awk -F: '{print $1}' /etc/passwd (打印第 1 列) |
NF | 当前行的字段总数(列数) | awk -F: '{print NF}' /etc/passwd (打印每行列数) |
NR | 当前处理行的全局行号(跨文件连续计数) | awk '{print NR,$0}' file1 file2 (带全局行号打印) |
FNR | 当前处理行的文件内行号(新文件重新计数) | awk '{print FNR,$0}' file1 file2 (每个文件行号从 1 开始) |
FS | 输入字段分隔符(同-F ,需在 BEGIN 块定义) | awk 'BEGIN{FS=":"}{print $1}' /etc/passwd |
OFS | 输出字段分隔符(默认空格,需在 BEGIN 块定义) | awk 'BEGIN{FS=":";OFS="---"}{print $1,$2}' /etc/passwd (输出用 --- 分隔) |
FILENAME | 当前处理的文件名 | awk '{print FILENAME,$0}' /etc/passwd |
二、实战案例分类解析
1. 基础字段提取(高频场景)
需求 | 命令 | 说明 |
---|---|---|
打印/etc/passwd 第 1 列(冒号分隔) | awk -F: '{print $1}' /etc/passwd | -F: 指定冒号为分隔符 |
打印/etc/passwd 最后 1 列 | awk -F: '{print $NF}' /etc/passwd | $NF 表示最后一个字段 |
打印包含 “root” 的行的第 1、6 列 | awk -F: '/root/{print $1,$6}' /etc/passwd | /root/ 是模式(匹配含 root 的行) |
打印第 2 行内容 | awk 'NR==2{print}' /etc/passwd | NR==2 是模式(匹配第 2 行) |
2. 统计与计算(生产常用)
需求 | 命令 | 说明 | |
---|---|---|---|
统计/etc/passwd 总行数 | awk 'END{print NR}' /etc/passwd | END 块在最后执行,NR 此时是总行数 | |
统计使用/bin/bash 的用户数 | awk -F: '/\/bin\/bash$/{x++}END{print x}' /etc/passwd | x++ 计数,END 打印结果 | |
计算内存使用率(百分比) | `free -m | awk '/Mem:/{print int($3/($2)*100)"%"}'` | int() 取整,$3已用内存,$2 总内存 |
统计$PATH 中路径的个数 | `echo $PATH | awk 'BEGIN{RS=":"}END{print NR}'` | RS=":" 指定冒号为行分隔符,每行是一个路径 |
3. 多文件处理与特殊分隔符
需求 | 命令 | 说明 |
---|---|---|
处理两个文件,打印文件内行号 | awk '{print FNR,FILENAME,$0}' file1 file2 | FNR 每个文件行号从 1 开始,FILENAME 显示文件名 |
用 “:” 和 “/” 同时作为分隔符 | awk -F[:/] '{print $9}' zz | -F[:/] 指定多个分隔符(: 或 /) |
输出时用制表符分隔字段 | awk -F: 'BEGIN{OFS="\t"}{print $1,$5}' /etc/passwd | OFS="\t" 定义制表符为输出分隔符 |
4. 条件判断与逻辑运算
需求 | 命令 | 说明 | ||||
---|---|---|---|---|---|---|
打印第 3 列(UID)<10 的行 | awk -F: '$3<10{print $0}' /etc/passwd | $3<10 是关系表达式(数值比较) | ||||
打印第 3 列 < 10 **或** >=1000 的行 | `awk -F: '$3<10 | $3>=1000{print}' /etc/passwd` | ` | ` 表示 “或” | ||
打印第 1 列含 “ro” 且 字段数 = 7 的行 | awk -F: '$1~/ro/ && NF==7{print}' /etc/passwd | ~ 表示 “包含”,&& 表示 “与” | ||||
第 3 列 < 10 打印第 3 列,否则打印第 1 列 | awk -F: '{if($3<10)print $3;else print $1}' /etc/passwd | 单分支 if-else |
5. 数组与高级统计(生产重点)
需求 | 命令 | 说明 |
---|---|---|
统计 httpd 访问日志中每个 IP 的访问次数 | awk '{ip[$1]++}END{for(i in ip)print ip[i],i}' /var/log/httpd/access_log | ip[$1]++ :以 IP 为数组下标,每出现一次计数 + 1;for 循环遍历数组 |
统计/var/log/secure 中失败登录的 IP 次数 | awk '/Failed password/{ip[$11]++}END{for(i in ip)print i","ip[i]}' /var/log/secure | 失败登录行中第 11 列是 IP,用数组计数 |
遍历数组打印键值对 | awk 'BEGIN{a[0]=10;a["name"]="test";for(i in a)print i,a[i]}' | awk 数组下标支持数字和字符串 |
6. 调用 Shell 命令与脚本编写
需求 | 命令 / 脚本 | 说明 |
---|---|---|
统计/etc/passwd 中/bin/bash 用户数(调用wc -l ) | awk -F: '/bash$/{print | "wc -l"}' /etc/passwd | 命令print:将结果传给 Shell 命令处理 |
编写脚本:失败登录 IP 次数≥3 则告警 | #!/bin/bash x=$(awk '/Failed password/{ip[$11]++}END{for(i in ip)print i","ip[i]}' /var/log/secure) 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 次数,Shell 循环判断阈值 |
三、关键总结:AWK 与其他工具的分工
工具 | 核心优势 | 适用场景 |
---|---|---|
grep/egrep | 快速文本过滤 | 单纯查找、匹配字符串(如找含 root 的行) |
sed | 流编辑(修改文本) | 替换、删除、插入行(如批量替换字符) |
awk | 字段拆分与格式化输出 | 提取列、统计计算、生成报告(如统计 IP 次数、计算内存使用率) |
通过以上梳理,可快速定位 AWK 的核心用法 ——以 “字段” 为单位处理文本,结合模式(条件)和动作(操作),能高效解决 Linux 环境下的文本统计、信息提取需求,尤其在生产环境的日志分析、系统监控脚本中应用广泛。