当前位置:首页>Linux>awk是Linux 文本处理的三驾马车之一.

awk是Linux 文本处理的三驾马车之一.

  • 2026-09-02 20:15:17
awk是Linux 文本处理的三驾马车之一.

      awk 是一种强大的文本处理工具和编程语言,其名称取自三位创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母。它擅长处理结构化数据(如按行和列组织的文本),通常用于数据提取、报告生成和文本转换。

1. 基本语法

awk [选项] 'pattern { action }' 输入文件...

· pattern:匹配条件,决定何时执行后面的 action。如果省略,则对所有行执行 action。

· action:对匹配到的行执行的操作,用花括号 {} 包围。如果省略,则默认打印整行。

· 选项:常见的有 -F 指定字段分隔符,-v 定义变量等。

2. 工作原理

      awk 逐行扫描输入文件(或标准输入),将每行按指定的分隔符(默认为空白字符)切割成多个字段,然后依次执行 pattern 匹配和 action 操作。处理完所有行后,可执行 END 块中的代码。

处理流程可以概括为:

1. 执行 BEGIN 块中的代码(仅在读取输入前执行一次)。

2. 从输入中读取一行。

3. 对该行执行所有匹配的 pattern { action }。

4. 重复步骤 2-3 直到文件结束。

5. 执行 END 块中的代码(仅在读取完所有输入后执行一次)。

3. 调用 awk 的方式

· 命令行直接运行

  awk '/pattern/ {print $1}' file.txt

· 从文件读取脚本(适用于复杂脚本)

  awk -f script.awk file.txt

· 可执行脚本

    在脚本文件首行添加 #!/usr/bin/awk -f,然后赋予执行权限。

4. 模式和动作

· 模式(pattern) 可以是:

  · 正则表达式:/regex/

  · 关系表达式:$1 == "hello"

  · 范围模式:NR==1, NR==5(从第 1 行到第 5 行)

  · 特殊模式:BEGIN、END

  · 模式组合:使用 &&(与)、||(或)、!(非)

· 动作(action) 是用 {} 括起来的语句序列,包含:

  · 变量赋值

  · 打印语句(print、printf)

  · 控制语句(if、for、while 等)

  · 数组操作

  · 函数调用等

5. 内置变量

awk 提供了许多自动维护的变量:

变量   含义

FS     输入字段分隔符(默认空格或制表符)

OFS   输出字段分隔符(默认空格)

RS     输入记录分隔符(默认换行符)

ORS  输出记录分隔符(默认换行符)

NF    当前记录的字段数

NR    当前已处理的行数(从 1 开始)

FNR  当前文件中的行数(用于处理多个文件)

FILENAME 当前输入文件的文件名

$0       当前整行内容

$1, $2, ... 第 1、2... 个字段(字段编号从 1 开始)

示例:打印每行的行号和第一个字段

awk '{print NR, $1}' file.tx

6. 运算符

· 赋值:=, +=, -=, *=, /=, %=

· 比较:==, !=, <, <=, >, >=

· 匹配:~(匹配正则),!~(不匹配)

· 逻辑:&&, ||, !

· 算术:+, -, *, /, %

· 三元:条件 ? 表达式1 : 表达式2

· 连接:空格(用于字符串拼接)

7. 控制语句

· 条件判断

  if (条件) {

      语句块

  } else if (条件) {

      语句块

  } else {

      语句块

  }

· 循环

  while (条件) {

      语句块

  }

  for (初始化; 条件; 更新) {

      语句块

  }

  # 遍历数组

  for (键 in 数组) {

      语句块

  }

· 跳出:break, continue, next(跳过当前行,开始下一行), exit(退出 awk

8. 数组

awk 支持关联数组(使用字符串作为下标)。

arr["key"] = value

delete arr["key"]   # 删除元素

if ("key" in arr)   # 检查元素是否存在

示例:统计文件中的单词出现次数

awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(w in count) print w, count[w]}' file.txt

9. 内置函数

· 字符串函数:

    length([s]) – 字符串长度

    index(s, t) – 返回子串 t 在 s 中的位置(从 1 开始)

    substr(s, i [, n]) – 返回 s 中从 i 开始的 n 个字符

    split(s, a [, sep]) – 将字符串 s 按分隔符 sep 分割到数组 a

    gsub(r, t [, s]) – 全局替换,返回替换次数

    sub(r, t [, s]) – 第一次替换

    match(s, r [, a]) – 正则匹配,返回位置

    toupper(s) / tolower(s) – 大小写转换

· 数学函数:

    sin(x), cos(x), sqrt(x), rand(), srand([x]), int(x) 等

· 时间函数(gawk 扩展):

    systime() – 返回当前时间戳

    strftime([format [, timestamp]]) – 格式化时间

10. 常用示例

a) 打印指定列

awk '{print $1, $3}' data.txt

b) 使用自定义分隔符

awk -F':' '{print $1}' /etc/passwd   # 打印用户名

c) 条件过滤

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

d) 使用 BEGIN 和 END

awk 'BEGIN {print "开始处理"} {print $0} END {print "处理完成"}' file.txt

e) 求和、平均值

awk '{sum += $1} END {print "总和:", sum, "平均值:", sum/NR}' numbers.txt

f) 格式化输出(printf)

awk '{printf "姓名:%-10s 年龄:%d\n", $1, $2}' students.txt

g) 多文件处理

awk 'FNR==1 {print "处理文件:" FILENAME} {print $0}' file1.txt file2.txt

h) 合并两个文件(类似 join)

假设 file1 包含 ID 和姓名,file2 包含 ID 和分数:

awk 'NR==FNR {a[$1]=$2; next} $1 in a {print $1, a[$1], $2}' file1 file2

i) 去除重复行(保留首次出现)

awk '!seen[$0]++' file.txt

11. 高级技巧

· 传递外部变量:使用 -v 选项

  awk -v threshold=100 '$1 > threshold' data.txt

· 从 Shell 命令获取输入

  awk '{print $1}' <(grep "error" log.txt)

· 生成随机数:rand() 和 srand()

· 使用自定义函数

  function max(a, b) {

      return a > b ? a : b

  }

  { print max($1, $2) }

12. 总结

      awk 是 Linux 文本处理的瑞士军刀,适合快速处理结构化数据。掌握它需要熟悉其数据模型(记录和字段)、内置变量、模式匹配以及编程结构。多练习常用场景(如日志分析、报表生成)是提高的关键。

     对于更复杂的任务,可以结合 sed、grep、sort、uniq 等命令,形成强大的管道处理链。如果遇到性能瓶颈或需要更复杂的数据结构,可以考虑使用 Perl 或 Python,但 awk 的简洁性和效率在大多数情况下仍然是无与伦比的。

最新文章

随机文章