AWK 命令行文本处理实战指南:模式-动作模型、内置函数与完整脚本(learnxinyminutes-docs 详解) 文档教程【免费下载链接】learnxinyminutes-docsCode documentation written as code! How novel and totally my idea!项目地址https://gitcode.com/gh_mirrors/le/learnxinyminutes-docs点击查看免费下载AWK 是每个 POSIX 兼容 UNIX 系统中默认携带的标准文本处理工具本指南以 learnxinyminutes-docs 仓库中 fr/awk.md 的完整教程为主线系统讲解 AWK 的程序结构、字段分隔机制、内置函数库与规则-动作编程模型。读完本文你将能够独立编写可复用的 AWK 脚本在 shell 中直接调用 AWK 完成按行读取、按分隔符切分、正则匹配过滤与统计汇总等日常文本处理任务。AWK 是什么UNIX 自带的文本处理利器AWK 是一个标准的命令行工具存在于每一个符合 POSIX 规范的 UNIX 系统中。它的定位与 Perl 相似——同样是擅长文本处理与脚本编程的语言——但它拥有 C 风格的语法、无需手动内存管理、没有静态类型并且默认就随 UNIX/Linux 发行版一起安装这是它在实际运维与数据处理场景中被广泛使用的重要原因。为什么要用 AWK 而不是 Perl主要在于AWK 是 UNIX 的一部分绝大多数 UNIX/Linux 系统默认自带同时 AWK 比 Perl 更易读。对于逐行读取文件、按分隔符拆分字段这类简单文本处理任务AWK 往往正是最合适的工具。在 learnxinyminutes-docs 仓库中这份 AWK 教程采用以带注释的合法代码讲语法的经典体例英文原文为根目录下的 awk.md本文所讲解的 fr/awk.md 是其法语翻译版。仓库还提供了 es/awk.md西班牙语、pt-br/awk.md葡萄牙语、uk/awk.md乌克兰语、zh-cn/awk.md简体中文等多个语言版本方便不同语言背景的读者对照学习。所有文档的 YAML 头部信息贡献者、译者等由仓库的 lint/frontmatter.py 脚本统一校验保证了多语言教程的格式一致性。AWK 的调用方式有两种在 shell 脚本中直接调用例如awk pattern { action } file.txt作为独立脚本语言运行脚本首行写#!/usr/bin/awk -f赋予执行权限后直接运行。程序骨架规则pattern与动作actionAWK 程序由一系列规则pattern和动作action组成形式为pattern1 { action; } pattern2 { action; }AWK 会自动读取并解析你提供的每一个文件中的每一行称为一条记录 record这构成一个隐式的循环每条规则就像循环体内的 switch 分支当某一行满足 pattern 条件时对应的 action 块被执行否则跳过。字段分隔符 FS 与选项 -F每一行在被处理前都会按字段分隔符FSField Separator切分成多个字段FS 的默认值是空白多个空格或 Tab 视为一个分隔符。你可以在命令行用-F选项指定awk -F: { print $1 } /etc/passwd # 按冒号切分也可以在 BEGIN 块中直接给 FS 赋值。与之相对的是输出字段分隔符OFS默认是一个空格同样可以赋值。特殊规则 BEGIN 与 ENDBEGIN在所有文件被读取之前执行适合放置初始化代码。如果脚本没有要处理的文本文件BEGIN 就是整个程序的主入口。END在最后一个文件读取到 EOFEnd Of File之后执行与 BEGIN 不同END 只有在确实提供了输入文件或标准输入时才会运行通常用于输出最终汇总报告。来看一段最基础的 BEGIN 用法节选自 fr/awk.md#!/usr/bin/awk -f BEGIN { # 变量是全局的无需声明即可使用 count 0; # 运算符与 C 及其同类语言C#、C 等一致 a count 1; # 加法 b count - 1; # 减法 c count * 1; # 乘法 d count / 1; # 除法 e count % 1; # 取模整数除法的余数 f count ^ 1; # 幂运算 a 1; b - 1; c * 1; d / 1; e % 1; f ^ 1; # 自增 / 自减 1 a; b--; # 作为前缀运算符时返回的是自增/自减之后的值 a; --b; }BEGIN 块内控制流、比较与正则匹配条件判断与循环AWK 的控制语句与 C 系语言完全一致且语句末尾的分号不是强制要求但写单行命令时建议加上BEGIN { # if / else if (count 0) print Nombre de départ 0; else print Hein?; # 三元运算符 print (count 0) ? Nombre de départ 0 : Hein?; # while 循环多行语句用花括号包裹 while (a 10) { print 字符串拼接 就是把一串 空格分隔的字符串 连在一起; print a; a; } # 经典 for 循环 for (i 0; i 10; i) print le bon vieux for pour les boucles; }注意字符串拼接的写法字符串 字符串——相邻的字符串字面量之间不需要任何运算符空格分隔即拼接。比较与逻辑运算符# a b 小于 # a b 小于等于 # a ! b 不等于 # a b 等于 # a b 大于 # a b 大于等于 # a b 逻辑与ET # a || b 逻辑或OU正则表达式匹配AWK 对正则表达式有一等公民的支持用~匹配和!~不匹配运算符BEGIN { if (foo ~ ^fo$) print Fooey!; if (boo !~ ^fo$) print Boo!; }数组索引、关联与多维AWK 的数组无需声明即可使用底层全部是关联数组以字符串为键的哈希表这为数据处理带来极大灵活性BEGIN { # 普通索引数组 arr[0] foo; arr[1] bar; # 用 split() 初始化数组按 : 切分 foo:bar:baz n split(foo:bar:baz, arr, :); # 结果arr[1]foo, arr[2]bar, arr[3]baz, n3 # 关联数组以字符串为键 assoc[foo] bar; assoc[bar] baz; # 多维数组存在某些此处不展开的限制 multidim[0,0] foo; multidim[0,1] bar; multidim[1,0] baz; multidim[1,1] boo; # 用 in 测试键是否存在 if (foo in assoc) print Fooey!; # 用 for...in 遍历所有键 for (key in assoc) print assoc[key]; }命令行参数ARGV 与 ARGC命令行参数保存在特殊数组ARGV中参数个数保存在ARGC中。一个非常实用的技巧是用delete删除某些参数从而阻止 AWK 把该参数当作待处理的文件名BEGIN { # 遍历并打印所有命令行参数 for (argnum in ARGV) print ARGV[argnum]; # 删除第 2 个参数防止 AWK 把它当作输入文件 delete ARGV[1]; # 打印参数个数 print ARGC; }函数定义方式与三类内置函数自定义函数与局部变量技巧AWK 中所有变量默认都是全局的——这是 AWK 最令人头疼的一点短脚本无碍长脚本容易引发命名冲突。解决办法是一个经典的hack函数参数在函数内部是局部的而 AWK 允许你声明比实际需要更多的参数。把多余的参数当作局部变量使用并用额外空格分隔以区分真实参数与局部变量function arithmetic_functions(a, b, c, d) { # a、b、c 是真实参数d 仅仅是局部变量 # 注意声明中 a, b, c 与 d 之间的多个空格是约定俗成的写法 ... return d; }原文档将 AWK 的内置函数划分为三大类算术函数、字符串函数、I/O 函数下面逐一展开。算术函数大多数 AWK 实现都提供标准的三角函数与数学函数function arithmetic_functions(a, b, c, d) { d sin(a); # 正弦 d cos(a); # 余弦 d atan2(b, a); # 反正切b / a d exp(a); # 指数 d log(a); # 对数 d sqrt(a); # 平方根 d int(5.34); # 截断小数部分取整d 5 srand(); # 随机数种子默认使用系统时间作为种子 d rand(); # 返回 [0, 1) 之间的随机数 return d; # 用 return 返回值 }字符串函数AWK 作为文本处理语言字符串函数最为常用且多数依赖正则表达式function string_functions( localvar, arr) { # sub() 只替换第一处匹配gsub() 替换所有匹配 # 两者都返回被替换的次数 localvar fooooobar; sub(fo, Meet me at the , localvar); # localvar Meet me at the bar gsub(e, ., localvar); # localvar M..t m. at th. bar # match() 返回正则匹配的位置index() 功能相同但不支持正则 match(localvar, t); # 4t 是第 4 个字符 # split() 按分隔符切分字符串到数组 n split(foo-bar-baz, arr, -); # 结果arr[1]foo; arr[2]bar; arr[3]baz; n3 # 其他实用函数 sprintf(%s %d %d %d, Testing, 1, 2, 3); # Testing 1 2 3 substr(foobar, 2, 3); # oob substr(foobar, 4); # bar length(foo); # 3 tolower(FOO); # foo toupper(foo); # FOO }I/O 函数print、printf 与文件句柄function io_functions( localvar) { # print 输出 print Hello world; # printf 格式化输出 printf(%s %d %d %d\n, Testing, 1, 2, 3); # AWK 没有真正的文件句柄概念当你用到需要文件的操作时 # 它会自动为你打开用于打开文件的那个字符串即可当作句柄使用。 # 注意相同输出的前提下字符串必须完全一致所以请用变量保存。 outfile /tmp/foobar.txt; print foobar outfile; close(outfile); # 关闭句柄 # 在 shell 中执行命令 system(echo foobar); # 输出 foobar # 从标准输入读取一行存入变量 getline localvar; # 从管道读取一行用字符串保存命令以便正确关闭 echo foobar | getline localvar; # localvar foobar close(echo foobar); # 从文件读取一行存入变量 infile /tmp/foobar.txt; getline localvar infile; close(infile); }getline有三种读取来源标准输入、管道命令 | getline、文件getline 变量 文件是 AWK 中灵活处理多路输入的关键函数。规则与动作实战逐行处理文本字段当传入文件参数时AWK 会按顺序处理所有文件。每一行被隐式切分后规则模式被逐一测试命中的动作被执行。下面看正则规则与字段变量# 对每个匹配 /^fobar$/ 的行执行动作不匹配的行直接跳过 /^fobar$/ { # print 不带参数时默认打印 $0 # $0 是当前正在处理的整行由 AWK 自动创建 print; # 每个字段用 $ 符号访问类似 shell 的 $1、$2... # 打印该行的第 2 个和第 4 个字段 print $2, $4; # NF 是当前行的字段个数Number of Fields print NF; # $NF 是最后一个字段 print $NF; }每条规则其实都是条件测试规则模式本质上是一个真/假测试# 只要 a 0 为真每一行都会执行该动作 a 0 { # 对每一行执行只要测试为真 } # 正则表达式也是条件测试没有指定测试对象时默认测试 $0 $0 /^fobar/ { print la ligne commence par foobar; } # 与上面的写法等价显式写出 $0 ~ /正则/ $0 ~ /^fobar$/ { print Equivalent to the last pattern; } # 测试整行是否只包含字母数字字符 /^[a-zA-Z0-9]$/ { print 当前行只包含字母数字字符。; }这里的关键理解是/^fobar$/ { ... }是$0 ~ /^fobar$/ { ... }的省略写法——模式匹配的对象默认就是当前行$0。综合实例统计某个名字的平均年龄以下完整脚本展示了 BEGIN 交互输入、规则筛选、END 汇总的完整协作是 AWK 擅长的完美用例。假设数据文件people.txt内容为Bob Jones 32 Jane Doe 22 Steve Stevens 83 Bob Smith 29 Bob Barker 72脚本avg-age.awk#!/usr/bin/awk -f BEGIN { # 向用户询问想要统计的名字 print Pour quel prénom voudriez vous savoir lage moyen ?; # 从标准输入读取一行而不是命令行文件 getline name /dev/stdin; } # 对每个第一个字段等于该名字的行执行 $1 name { # 此处可以访问多个 AWK 预置变量 # $0 整行 # $3 第三个字段年龄正是我们关心的 # NF 字段个数此处为 3 # NR 到目前为止已处理的记录行数 # FILENAME 当前正在处理的文件名 # FS 当前使用的字段分隔符这里是空格 # ... 更多变量见 man awk # 累加年龄总和与匹配行数 sum $3; nlines; } # END 在处理完全部文件后执行通常用于输出最终报告 END { if (nlines) print Lage moyen pour le prénom name est sum / nlines; }运行方式chmod x avg-age.awk ./avg-age.awk people.txt # 输入 Bob输出Lage moyen pour le prénom Bob est 44.3333这个例子完整串起了本文的全部知识点BEGIN中的初始化与/dev/stdin读取、$1 name的条件规则、sum/nlines的跨规则全局变量累加以及END中的最终汇总——逐行读取 → 按规则筛选 → 聚合输出正是 UNIX 文本处理中 AWK 的典型工作流。深入学习建议本机执行man awk可查阅完整手册原文档fr/awk.md在 Further Reading 一节列出的参考资料还包括AWK 入门教程、GNU Awk 用户指南GNU Awk 是大多数 Linux 系统的默认实现以及 AWK 单行脚本合集等。在 learnxinyminutes-docs 仓库中可以对照阅读英文原版 awk.md 以及 es/awk.md、pt-br/awk.md、uk/awk.md、zh-cn/awk.md 等多语言版本用不同语言重新梳理同一套概念是巩固记忆的有效方式。仓库的 CONTRIBUTING.md 与 README.md 说明了此类教程文档的编写规范若你有意贡献新的语言版本可参考现有译文结构并借助 lint/frontmatter.py 校验 YAML 头部格式。AWK 的核心思想可以浓缩为一句话把逐行读取、按分隔符切分、按规则筛选、按动作处理这四件事内建到语言里你只需要专注于期望什么样的输入、想对输入做什么剩下的交给 AWK 的隐含循环即可。赞分享文档教程【免费下载链接】learnxinyminutes-docsCode documentation written as code! How novel and totally my idea!项目地址https://gitcode.com/gh_mirrors/le/learnxinyminutes-docs点击查看免费下载相关推荐learnxinyminutes-docs 中的 AWK 实战指南模式-动作编程、内置函数与文本处理全解析learnxinyminutes docs 中的 AWK 实战指南模式 动作编程、内置函数与文本处理全解析 本篇文章以 learnxinyminutes do文档教程AWK 快速上手用模式与动作征服文本处理的实战指南learnxinyminutes-docsAWK 快速上手用模式与动作征服文本处理的实战指南learnxinyminutes docs AWK 是每个 POSIX 兼容 UNIX 系统上都自带的标文档教程Bash 内建命令 return 详解函数退出状态码与脚本错误处理实战Bash 内建命令 return 详解函数退出状态码与脚本错误处理实战 导读 return 是 Bash 中最常用的内建命令之一它负责让 shell 函数主文档教程上一篇GHelper 上手教程免费轻量替代 Armoury Crate一个文件搞清华硕 ROG 性能控制下一篇baidupankey 百度网盘提取码解析工具3秒拿到提取码完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考