一键处理文本awk命令小结

一、命令介绍与原理

1.1 介绍

awk 是一种功能强大的文本处理编程语言,以其三位创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母命名。它不仅是文本处理工具,更是一门完整的编程语言,特别适合处理结构化数据和生成报告。

1.2 工作原理

记录-字段模型:将输入文本视为记录的集合,每条记录由字段组成

模式-动作对:程序由一系列 模式 { 动作 } 对组成

自动字段分割:根据字段分隔符自动将记录分割为字段

内置变量管理:维护 NR、NF、FS、OFS 等内置变量

流式处理:逐行处理输入,支持管道和文件输入

2. 基本语法

awk [选项] '模式 { 动作 }' 输入文件
awk [选项] -f 脚本文件 输入文件

2.1 常用选项

-F fs
--field-separator=fs   # 指定字段分隔符
-v var=value                  # 定义变量并赋值
-f program-file, --file program-file  # 从文件读取awk程序
-W option                     # 兼容性选项
--posix                       # 启用POSIX兼容模式
--dump-variables[=file]       # 输出全局变量到文件
--profile[=file]              # 输出性能分析信息

2.2 基本程序结构

# 完整结构
awk 'BEGIN { 初始化动作 } 
     模式1 { 动作1 }
     模式2 { 动作2 }
     END { 结束动作 }' 文件

三、经典使用场景

3.1 字段提取和显示

# 打印特定字段
awk '{print $1, $3}' file.txt           # 打印第1和第3字段
awk '{print $NF}' file.txt              # 打印最后一个字段
awk '{print $(NF-1)}' file.txt          # 打印倒数第二个字段
# 重新排列字段
awk '{print $3, $1, $2}' file.txt       # 重新排列字段顺序

3.2 条件过滤

# 数值条件
awk '$3+0 > 100' data.txt               # 第3字段大于100的行
awk '$1 + $2 > 50' data.txt             # 前两个字段和大于50
awk 'NR % 2 == 0' file.txt              # 偶数行
# 字符串匹配
awk '/error/' logfile.txt               # 包含"error"的行
awk '$2 == "success"' status.txt        # 第2字段等于"success"
awk 'tolower($2) == "sucess"' status    # 忽略大小写 
awk '$1 ~ /^[0-9]+$/' file.txt          # 第1字段为数字

3.3 数据统计和汇总

# 求和与计数
awk '{sum += $1} END {print sum}' data.txt          # 第1字段求和
awk '{count++} END {print count}' file.txt          # 行数统计
awk '$3 > 50 {count++} END {print count}' data.txt  # 条件计数
# 平均值计算
awk '{sum += $1; count++} END {print sum/count}' data.txt

四、与其他工具命令结合使用

4.1 与 grep 结合

# 先用grep过滤,再用awk处理
grep "ERROR" logfile | awk '{print $1, $5}'
# 在awk中实现grep功能
awk '/ERROR/ {print $0}' logfile
# 组合过滤和处理
ps aux | grep python | awk '{sum += $4} END {print "内存使用:", sum "%"}'

4.2 与 sed 结合

# sed预处理,awk分析
sed 's/:/ /g' data.txt | awk '{print $1, $2}'
# awk处理sed输出
sed -n '1,100p' largefile.txt | awk '{print NR, $0}'
# 复杂管道处理
cat logfile | sed 's/  */ /g' | awk '{print $1, $NF}'

4.3 与 sort/uniq 结合

# 统计频率分布
awk '{print $1}' access.log | sort | uniq -c | sort -nr
# 在awk中排序输出
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log | sort -k2nr

4.4 在 Shell 脚本中应用

#!/bin/bash
# 系统监控脚本
monitor_system() {
    # 添加错误处理
    if ! command -v free &> /dev/null; then
        echo "错误: free命令不存在"
        return 1
    fi

    # 内存监控 - 更精确
    free -m | awk 'NR==2{
        if($2 > 0) 
            printf "内存使用率: %.2f%%\n", $3*100/$2
        else
            print "错误: 无法获取内存信息"
    }'

    # 磁盘监控 - 排除特殊文件系统
    df -h | awk '$1 !~ /(tmpfs|devtmpfs)/ && $5+0 > 80 {
        print "警告: "$1" 使用率 "$5
    }'
}

五、进阶应用场景

5.1 报告生成

#!/bin/bash
# 系统报告生成器
generate_system_report() {
    local report_file="/tmp/system_report_$(date +%Y%m%d).txt"
    cat > "$report_file" << 'EOF'
=== 系统报告 ===
生成时间: $(date)
EOF
    # 添加用户统计
    echo "=== 用户统计 ===" >> "$report_file"
    awk -F: '
    $3 >= 1000 { regular_users++ }
    $3 < 1000 { system_users++ }
    END {
        print "普通用户:", regular_users
        print "系统用户:", system_users
        print "总用户数:", regular_users + system_users
    }' /etc/passwd >> "$report_file"
    # 添加进程统计
    echo -e "\n=== 进程统计 ===" >> "$report_file"
    ps aux | awk '
    NR>1 {
        cpu_sum += $3
        mem_sum += $4
        user_count[$1]++
    }
    END {
        print "总CPU使用:", cpu_sum "%"
        print "总内存使用:", mem_sum "%"
        print "活跃用户数:", length(user_count)
    }' >> "$report_file"
    echo "报告已生成: $report_file"
}

5.2 与其他命令的对比

# awk vs cut
awk '{print $1}' file.txt        # 更灵活,支持条件
cut -d' ' -f1 file.txt           # 更简单,性能更好
# awk vs sed
awk '/pattern/ {print $1}'       # 字段处理能力强
sed -n '/pattern/p'              # 简单的行过滤
# awk vs Perl/Python
awk '{sum+=$1} END{print sum}'   # 简单的数据汇总
# 复杂的数据处理更适合使用Perl或Python

六、总结

通过深入掌握 awk 命令,可以构建强大的文本数据处理流水线。无论是简单的字段提取还是复杂的数据分析,awk 都提供了高效灵活的解决方案。作为一门完整的编程语言,awk 的学习投入将在日常工作中带来巨大的回报。

posted @ 2025-12-05 04:19  hihibig  阅读(21)  评论(0)    收藏  举报