Linux awk 命令

发布于:2025-07-05 ⋅ 阅读:(17) ⋅ 点赞:(0)

以下是关于 Linux 中 awk 命令的详细讲解,涵盖其基本概念、语法、内置变量、控制结构以及实际应用示例。


一、AWK 简介

AWK 是一种用于 模式扫描和处理 的文本处理工具,由 Aho、Weinberger 和 Kernighan 三位科学家共同开发(名字首字母缩写)。它特别适合处理 结构化文本数据(如日志、CSV 文件、配置文件等),支持字段操作、条件判断、数学运算、字符串处理等功能。

核心特点
  1. 逐行处理:按行读取输入数据,每行称为一条“记录”。
  2. 字段分割:默认以空格或制表符作为字段分隔符,可通过 -F 自定义分隔符。
  3. 模式匹配:基于正则表达式或条件筛选文本。
  4. 字段操作:轻松访问和操作文本中的字段(如 $1 表示第一个字段)。
  5. 算术与逻辑运算:支持加减乘除、条件判断等。
  6. 内置函数:提供字符串处理(如 length())、数学函数(如 sqrt())等。
  7. 可移植性:适用于大多数类 Unix 系统。

二、基本语法

awk [选项] '模式 {动作}' 文件名
  • 模式(Pattern):决定是否对某行执行动作(可选)。
  • 动作(Action):对匹配行执行的操作(如打印、计算等)。
  • 文件名:要处理的输入文件(可选,若未指定则从标准输入读取)。
常见选项
  • -F 分隔符:指定字段分隔符(默认为空格)。
  • -v var=value:定义变量。
  • -f 脚本文件:从文件中读取 AWK 脚本。

三、工作原理

  1. 读取输入:逐行读取文件或输入流。
  2. 分割字段:根据分隔符将每行分割为字段(默认以空格/制表符分隔)。
  3. 匹配模式:检查当前行是否符合指定模式。
  4. 执行动作:对匹配行执行操作(如打印字段、计算值等)。
  5. 输出结果:将处理后的结果输出。

四、内置变量

变量名 说明
$0 当前行的整行内容
$1, $2,... 第1、第2…个字段(从1开始计数)
NF 当前行的字段总数
NR 总行号(跨文件连续计数)
FNR 当前文件的行号(每个文件单独计数)
FS 输入字段分隔符(默认为空格)
OFS 输出字段分隔符(默认为空格)
RS 输入记录分隔符(默认为换行符)
ORS 输出记录分隔符(默认为换行符)
FILENAME 当前处理的文件名
示例
# 打印每行的字段数和整行内容
awk '{print NF, $0}' file.txt

# 打印第三字段大于50的行
awk '$3 > 50 {print $1, $3}' file.txt

五、控制结构

1. 条件判断
# 判断字段值并输出
awk '{if ($1 == "root") print $2}' /etc/passwd
2. 循环
# 遍历字段
awk '{for(i=1; i<=NF; i++) print $i}' file.txt
3. 数组
# 统计字段出现次数
awk '{count[$1]++} END {for (key in count) print key, count[key]}' file.txt
4. 函数
# 自定义函数:计算平均值
awk '
function avg(total, count) {
    return total / count
}
{sum += $1; n++}
END {print "平均值:", avg(sum, n)}
' data.txt

六、内置函数

字符串处理函数
  • gsub(r, s [, t])

    • 功能:全局替换字符串或正则表达式 rs,作用范围默认是整个记录($0),可指定目标字段 t

    • 示例

      awk '{gsub(/old/, "new", $1); print $0}' file.txt
      
    • sub(r, s [, t])

    • 功能:替换第一个匹配的 rs,作用范围同上。

    • 示例

      awk '{sub(/old/, "new", $1); print $0}' file.txt
      
  • index(s, t)

    • 功能:返回子串 t 在字符串 s 中的首次出现位置(从 1 开始计数),未找到返回 0。

    • 示例

      awk '{print index("hello world", "world")}'  # 输出 7
      
  • split(s, a [, fs])

    • 功能:按分隔符 fs 将字符串 s 拆分成数组 a,返回拆分后的元素个数。

    • 示例

      awk '{split("apple,banana,orange", arr, ","); for(i in arr) print arr[i]}'
      
  • substr(s, p [, n])

    • 功能:从位置 p 开始截取字符串 s,长度为 n(可选),若未指定 n 则截取到末尾。

    • 示例

      awk '{print substr("hello", 2, 3)}'  # 输出 "ell"
      
  • length([s])

    • 功能:返回字符串 s 的长度(或当前记录 $0 的长度)。

    • 示例

      awk '{print length($0)}' file.txt  # 输出每行的字符数
      
  • tolower(s) / toupper(s)

    • 功能:将字符串 s 转换为全小写/全大写。

    • 示例

      awk '{print tolower("MiXeD cAsE")}'  # 输出 "mixed case"
      
数学运算函数
  • int(expr)

    • 功能:返回 expr 的整数部分(向下取整)。

    • 示例

      awk 'BEGIN {print int(3.7)}'  # 输出 3
      
  • sqrt(expr)

    • 功能:返回 expr 的平方根。

    • 示例

      awk 'BEGIN {print sqrt(16)}'  # 输出 4
      
  • sin(x) / cos(x) / log(x) / exp(x)

    • 功能:三角函数和自然对数/指数运算(输入为弧度)。

    • 示例

      awk 'BEGIN {print sin(3.14159265/2)}'  # 输出 1.0
      
  • rand() / srand([seed])

    • 功能:生成 [0, 1) 区间的随机数,srand 可设置随机种子(默认使用时间戳)。

    • 示例

      awk 'BEGIN {srand(); print int(100*rand())}'  # 输出 0-99 的随机整数
      
数组与数据操作
  • asort(array, [sorted_array])

    • 功能:对数组 array 进行排序,结果存储在 sorted_array(可选)。

    • 示例

      awk 'BEGIN {arr[0]="banana"; arr[1]="apple"; asort(arr); for(i=1; i<=length(arr); i++) print arr[i]}'
      
  • split(s, a, fs)

    • 功能:拆分字符串为数组(如上所述)。
  • match(s, r [, arr])

    • 功能:检查字符串 s 是否匹配正则表达式 r,若匹配,返回起始位置,可将匹配结果存入数组 arr

    • 示例

      awk 'BEGIN {if (match("hello world", /world/)) print "Match found"}'
      
输入输出控制
  • close(file)

    • 功能:关闭文件或管道。

    • 示例

      awk '{print $0 > "output.txt"; close("output.txt")}'
      
  • fflush([file])

    • 功能:刷新输出缓冲区(常用于实时输出)。

    • 示例

      awk '{print $0; fflush()}'
      
  • system(command)

    • 功能:执行系统命令。

    • 示例

      awk '{system("date")}'  # 每行输出当前时间
      
其他实用函数
  • sprint(fmt, expr1, expr2, ...)

    • 功能:类似 printf,但返回格式化后的字符串(不直接输出)。

    • 示例

      awk 'BEGIN {str = sprintf("Value: %d", 42); print str}'
      
  • strtonum(str)

    • 功能:将字符串转换为数值(支持八进制、十六进制)。

    • 示例

      awk 'BEGIN {print strtonum("0x1F")}'  # 输出 31
      
时间处理函数
  • systime()

    • 功能:返回当前时间戳(秒数)。

    • 示例

      awk 'BEGIN {print systime()}'
      
  • strftime([format, timestamp])

    • 功能:格式化时间戳为可读字符串。

    • 示例

      awk 'BEGIN {print strftime("%Y-%m-%d %H:%M:%S")}'
      

七、BEGIN 和 END 块

  • BEGIN:在处理文本前执行(初始化操作)。

  • END:在处理完所有行后执行(总结操作)。

    awk 'BEGIN { print "Start processing" } 
         { sum += $1 } 
         END { print "Total sum:", sum }' data.txt
    

八、高级功能

1. 模式匹配
  • 正则表达式匹配:使用 /pattern/ 匹配行。
# 打印包含 "error" 的行
awk '/error/' file.log
  • 多模式匹配
# 打印包含 "error" 或 "warning" 的行
awk '/error/, /warning/' file.log
2. 格式化输出
  • printf:格式化输出(需手动添加换行符 \n)。
# 格式化输出行号和内容
awk '{printf "Line %d: %s\n", NR, $0}' file.txt
3. 处理多文件
# 同时处理多个文件并输出文件名
awk '{print FILENAME, $0}' file1.txt file2.txt

七、实际应用示例

1. 提取特定字段
# 提取 /etc/passwd 中用户名和用户ID
awk -F: '{print $1, $3}' /etc/passwd
2. 统计字段总和
# 提取特定字段或统计错误次数
awk '/ERROR/ { count++ } END { print "Total errors:", count }' access.log
3. 替换字段内容
# 将每行第二个字段替换为 "REPLACED"
awk '{$2 = "REPLACED"; print $0}' file.txt
4. 过滤特定行
# 打印包含 "success" 的行
awk '/success/ {print $0}' log.txt
5. 生成报表
# 生成学生平均成绩报告
awk '
{sum += $2; n++}
END {print "平均成绩:", sum/n}
' scores.txt

八、AWK 脚本编写

1. 编写脚本文件

创建 script.awk 文件:

{
    print $1, $NF
}
2. 执行脚本
awk -f script.awk file.txt

九、总结

  • 适用场景:日志分析、数据统计、文本格式化、自动化脚本等。
  • 优势:语法简洁,功能强大,适合处理结构化文本。
  • 学习建议:结合 grepsedcut 等工具,掌握 AWK 的变量、数组、函数等进阶功能。

👍 逆风的方向,更适合飞翔
😊 希望对你有帮助!


网站公告

今日签到

点亮在社区的每一天
去签到