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,专门处理表格型数据,提取、计算、报表一把抓。

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式