linux awk 命令

awk 是 Linux/Unix 系统中最强大的文本处理工具 之一,是一门完整的编程语言,专门用于处理结构化文本(按列分隔的数据)。


核心定位

工具 擅长处理
grep 按行筛选(找包含某内容的行)
sed 按行编辑(替换、删除)
awk 按列处理(提取、计算、格式化)

基本语法

复制代码
awk '模式 {动作}' 文件
awk 'pattern {action}' file

执行逻辑 :逐行读取文件,匹配模式 的行执行动作


核心概念:字段(列)

awk 自动按空格/制表符分割每行,生成内置变量:

变量 含义
$0 整行内容
$1 第1列
$2 第2列
$NF 最后一列(N umber of Fields)
$(NF-1) 倒数第2列
NF 当前行的列数

基础示例

1. 打印指定列(最常用)

复制代码
# 打印第1、3列(默认空格分隔)
awk '{print $1, $3}' file.txt

# 打印用户名和家目录(/etc/passwd 是冒号分隔)
awk -F: '{print $1, $6}' /etc/passwd

# 打印最后一列
awk '{print $NF}' file.txt

2. 指定分隔符 -F

复制代码
# CSV 文件(逗号分隔)
awk -F, '{print $2}' data.csv

# 多字符分隔符
awk -F' |,' '{print $1}' file.txt    # 空格或逗号

3. 条件过滤

复制代码
# 打印第3列大于100的行
awk '$3 > 100 {print $0}' data.txt

# 匹配正则:包含 "error" 的行
awk '/error/ {print $0}' log.txt

# 组合条件:第2列为 "success" 且第5列大于10
awk '$2=="success" && $5>10 {print $1}' log.txt

内置变量

变量 含义
NR 当前行号N umber of Record)
NF 当前行的列数
FS 输入分隔符(F ield Separator,默认空格)
OFS 输出分隔符(O utput FS,默认空格)
RS 输入记录分隔符(默认换行)
ORS 输出记录分隔符(默认换行)

进阶用法

1. BEGIN 和 END 块

复制代码
# BEGIN: 处理前执行(初始化)
# END: 处理后执行(汇总)

awk 'BEGIN {print "开始处理"} 
     {print NR, $0} 
     END {print "总行数:", NR}' file.txt

2. 计算统计

复制代码
# 求第3列的总和与平均
awk '{sum+=$3} END {print "总和:", sum, "平均:", sum/NR}' data.txt

# 统计行数(类似 wc -l)
awk 'END {print NR}' file.txt

# 找出文件第3列的最大值 NR==1为真,执行{max=$3} 其他行只检查$3>max,真则更新
awk 'NR==1 || $3>max {max=$3} END {print max}' data.txt

3. 格式化输出

复制代码
# printf 格式化(类似 C 语言)Name: %-10s	字符串格式:左对齐(-),占10个字符宽(10)
# Age: %3d	整数格式:右对齐(默认),占3个字符宽(3)
awk '{printf "Name: %-10s Age: %3d\n", $1, $2}' file.txt

# 对齐输出  %8.2f	第3列	右对齐(默认)	8字符	浮点数(2位小数)
awk '{printf "%-15s %10s %8.2f\n", $1, $2, $3}' report.txt

4. 修改字段内容

复制代码
# 替换第2列的值 将文件中每行的第2列替换为固定的字符串 "REPLACED",然后输出修改后的整行内容。
awk '{$2="REPLACED"; print $0}' file.txt

# 大小写转换
awk '{print toupper($0)}' file.txt    # 转大写
awk '{print tolower($1)}' file.txt    # 第1列转小写

实战场景

日志分析

复制代码
# 统计 HTTP 状态码出现次数
awk '{count[$9]++} END {for(code in count) print code, count[code]}' access.log

# 计算平均响应时间(假设第10列是响应时间)
awk '{sum+=$10; n++} END {print "Avg:", sum/n "ms"}' access.log

系统信息处理

复制代码
# 查看内存使用情况(过滤 + 计算)
free -m | awk '/Mem:/ {printf "内存使用率: %.2f%%\n", $3/$2*100}'

# 统计进程内存占用总和
ps aux | awk '{sum+=$6} END {print "总内存:", sum/1024 "MB"}'

数据处理

复制代码
# CSV 转 JSON(简化版)
awk -F, 'BEGIN {print "["} 
         {printf "%s{\"name\":\"%s\",\"age\":%s}", 
          (NR>1?",\n":""), $1, $2} 
         END {print "\n]"}' data.csv

# 去重(基于某列)
awk '!seen[$1]++' file.txt    # 保留第1列首次出现的行

与 grep、sed 配合

复制代码
# 管道组合:先过滤,再处理列
grep "error" app.log | awk '{print $1, $4, $NF}'

# 提取 + 替换
awk '{print $2}' data.txt | sed 's/old/new/'

# 复杂处理:awk 内部调用系统命令
awk '{system("mkdir " $1)}' dirs.txt    # 根据列内容创建目录

常用技巧速查

需求 命令
打印第2列 awk '{print $2}'
按逗号分隔取第3列 awk -F, '{print $3}'
打印行号 awk '{print NR, $0}'
过滤空行 awk NFawk '/./'
去重 awk '!a[$0]++'
替换分隔符输出 awk '{print $1","$2}' OFS=,
条件过滤后统计 awk '$3>50{c++} END{print c}'

完整脚本示例

复制代码
# 统计销售额报表
awk -F, '
    BEGIN {
        print "======== 销售报表 ========"
        print "日期       产品    金额"
        print "------------------------"
    }
    NR>1 {  # 跳过表头
        sum+=$3
        count[$2]++    # 按产品统计
        print $1, $2, $3
    }
    END {
        print "------------------------"
        print "总计:", sum
        print "产品种类:"
        for(p in count) print "  " p ": " count[p] "次"
    }
' sales.csv

总结

特性 说明
核心优势 按列处理、内置计算、格式化输出
语法 awk '模式{动作}' 文件
必记变量 $0, $1, $NF, NR, NF
必记选项 -F 指定分隔符

一句话awk 是命令行里的 Excel,专门处理表格型数据,提取、计算、报表一把抓。

相关推荐
向依阳2 小时前
RV1126准备-----编译和测试SDK自带的RKNN例程
linux·rv1226
我是谁??2 小时前
Rocky9+ Docker + 容器内Linux桌面环境 + Web远程
运维·docker·容器
阿虎儿2 小时前
Ubuntu 如何开启 Root 用户 SSH 登录
运维
the sun342 小时前
Linux驱动开发:环境准备与报错处理
linux·运维·服务器
MC_J2 小时前
Linux 6.1 移植RTL8723du驱动
linux·arm
彭泽布衣2 小时前
Linux如何指定源端口打流
linux·运维·网络
Ciel_75213 小时前
OpenClaw 深度进阶:记忆系统、多智能体架构与自动化调度全解析
运维·自动化
晨晖23 小时前
Linux命令3
linux·运维·服务器
素雨迁喜3 小时前
Linux平台下git工具的使用
linux·运维·git