Shell脚本编程开发实战(六):文本处理三剑客之 awk 完全攻略
Shell脚本编程开发实战六文本处理三剑客之 awk 完全攻略导读awk 是文本处理三剑客中最强大、最灵活的工具。它不仅是一个命令行工具更是一门完整的编程语言支持变量、条件判断、循环、数组、函数等编程特性。awk 擅长对结构化数据如 CSV、日志、表格进行提取、统计和格式化输出是运维工程师和数据分析师的必备技能。本文在远程 Ubuntu 服务器上完整实操 awk 的全部核心功能涵盖工作模式、内置变量、格式化输出、模式匹配、条件循环、字符串函数、数组和高阶实战案例共计 17 个知识模块每条命令均真实执行并捕获输出。目录1. awk 的工作模式与基本用法2. awk 内置变量3. printf 格式化输出4. 模式匹配5. 条件语句6. 循环语句7. 字符串函数8. 数组用法9. 多字段处理与分隔符10. 实际案例总结思考题测试数据准备# 学生成绩表空格分隔catstudents.txtEOF Tom 90 85 78 92 Jerry 76 89 95 70 Alice 88 92 90 85 Bob 65 70 60 75 Carol 95 90 88 93 David 80 85 82 78 Eve 70 75 68 72 Frank 85 88 90 87 Grace 92 95 90 88 Henry 78 82 80 76 EOF# 销售数据 CSVcatsales.csvEOF date,product,region,quantity,price 2025-01-01,Laptop,North,5,8000 2025-01-02,Mouse,South,50,50 2025-01-03,Keyboard,East,30,150 2025-01-04,Monitor,West,10,2000 2025-01-05,Laptop,South,3,8000 2025-01-06,Mouse,North,100,50 2025-01-07,Keyboard,West,45,150 2025-01-08,Monitor,East,8,2000 2025-01-09,Laptop,East,7,8000 2025-01-10,Mouse,West,80,50 EOF# 应用日志文件catwebapp.logEOF 2025-01-10 09:00:01 INFO UserLogin - user:admin, ip:192.168.1.1 2025-01-10 09:00:15 ERROR DatabaseConnection - Failed to connect to db:timeout 2025-01-10 09:00:30 INFO UserLogin - user:zhangsan, ip:192.168.1.2 2025-01-10 09:01:00 WARN MemoryUsage - Memory at 85% 2025-01-10 09:01:30 ERROR NullPointerException - at com.app.UserService:line 45 2025-01-10 09:02:00 INFO DataExport - Exported 500 records 2025-01-10 09:02:15 ERROR DatabaseConnection - Failed to connect to db:refused 2025-01-10 09:02:30 INFO UserLogin - user:lisi, ip:192.168.1.3 2025-01-10 09:03:00 WARN DiskSpace - Disk usage at 90% 2025-01-10 09:03:15 ERROR TimeoutException - Request timeout after 30s 2025-01-10 09:03:30 INFO DataImport - Imported 200 records 2025-01-10 09:04:00 ERROR NullPointerException - at com.app.OrderService:line 78 EOF# 员工信息文件逗号分隔catemployees.txtEOF 1,zhangsan,manager,15000 2,lisi,developer,12000 3,wangwu,developer,11000 4,zhaoliu,tester,9000 5,tianqi,manager,16000 6,zhouba,developer,13000 7,wujiu,tester,8500 8,zhengshi,manager,14000 EOF1. awk 的工作模式与基本用法awk 的基本语法为awk pattern {action} file。它逐行读取文件对每一行执行 pattern 匹配匹配成功则执行 action。如果省略 pattern则对所有行执行 action如果省略 action则默认执行{print}。1.1 打印全部内容awk{print}students.txt输出结果Tom 90 85 78 92 Jerry 76 89 95 70 Alice 88 92 90 85 Bob 65 70 60 75 Carol 95 90 88 93 David 80 85 82 78 Eve 70 75 68 72 Frank 85 88 90 87 Grace 92 95 90 88 Henry 78 82 80 761.2 打印指定字段awk 默认以空格/Tab 为字段分隔符$1表示第一个字段$2表示第二个字段$0表示整行awk{print $1}students.txt输出结果Tom Jerry Alice Bob Carol David Eve Frank Grace Henry打印多个字段awk{print $1, $2}students.txt输出结果Tom 90 Jerry 76 Alice 88 Bob 65 Carol 95 David 80 Eve 70 Frank 85 Grace 92 Henry 78解析awk 自动将每行按分隔符切分为字段通过$N直接引用。这是 awk 最基础也最常用的功能比cut命令更灵活因为可以任意组合字段顺序。2. awk 内置变量awk 提供了丰富的内置变量用于获取行号、字段数、分隔符等信息。变量说明示例NR当前记录号行号{print NR}NF当前行的字段数{print NF}$NF最后一个字段的值{print $NF}FS输入字段分隔符BEGIN{FS:}OFS输出字段分隔符BEGIN{OFSRS输入记录分隔符BEGIN{RS}FILENAME当前文件名{print FILENAME}2.1 NR - 行号awk{print NR, $1}students.txt输出结果1 Tom 2 Jerry 3 Alice 4 Bob 5 Carol 6 David 7 Eve 8 Frank 9 Grace 10 Henry2.2 NF - 字段数awk{print NR, NF, $1}students.txt输出结果1 5 Tom 2 5 Jerry 3 5 Alice 4 5 Bob 5 5 Carol 6 5 David 7 5 Eve 8 5 Frank 9 5 Grace 10 5 Henry2.3 $NF - 最后一个字段awk{print $1, $NF}students.txt输出结果Tom 92 Jerry 70 Alice 85 Bob 75 Carol 93 David 78 Eve 72 Frank 87 Grace 88 Henry 762.4 FILENAME - 文件名awk{print FILENAME, NR, $1}students.txt输出结果students.txt 1 Tom students.txt 2 Jerry students.txt 3 Alice students.txt 4 Bob students.txt 5 Carol students.txt 6 David students.txt 7 Eve students.txt 8 Frank students.txt 9 Grace students.txt 10 Henry2.5 FS - 指定字段分隔符使用-F选项指定分隔符处理/etc/passwd文件awk-F:{print $1, $7}/etc/passwd|head-5输出结果root /bin/bash daemon /usr/sbin/nologin bin /usr/sbin/nologin sys /usr/sbin/nologin sync /bin/sync2.6 OFS - 输出字段分隔符awk-F,BEGIN{OFS | } {print $1, $2, $4}employees.txt输出结果1 | zhangsan | 15000 2 | lisi | 12000 3 | wangwu | 11000 4 | zhaoliu | 9000 5 | tianqi | 16000 6 | zhouba | 13000 7 | wujiu | 8500 8 | zhengshi | 14000解析OFS控制输出时字段之间的分隔符。当print语句中使用逗号分隔多个值时awk 会用OFS的值连接它们。这在格式化报表输出时非常有用。3. printf 格式化输出awk 的printf函数支持 C 语言风格的格式化输出能精确控制对齐、宽度和精度。3.1 基本格式化awk{printf %-10s %5d %5d %5d %5d\n, $1, $2, $3, $4, $5}students.txt输出结果Tom 90 85 78 92 Jerry 76 89 95 70 Alice 88 92 90 85 Bob 65 70 60 75 Carol 95 90 88 93 David 80 85 82 78 Eve 70 75 68 72 Frank 85 88 90 87 Grace 92 95 90 88 Henry 78 82 80 763.2 带表头的格式化表格awkBEGIN{ printf %-10s %8s %8s %8s %8s\n, Name, Score1, Score2, Score3, Score4 printf --------------------------------------------------\n } { printf %-10s %8d %8d %8d %8d\n, $1, $2, $3, $4, $5 }students.txt输出结果Name Score1 Score2 Score3 Score4 -------------------------------------------------- Tom 90 85 78 92 Jerry 76 89 95 70 Alice 88 92 90 85 Bob 65 70 60 75 Carol 95 90 88 93 David 80 85 82 78 Eve 70 75 68 72 Frank 85 88 90 87 Grace 92 95 90 88 Henry 78 82 80 763.3 浮点数格式化awk{total$2$3$4$5; printf %-10s Avg: %6.2f\n, $1, total/4}students.txt输出结果Tom Avg: 86.25 Jerry Avg: 82.50 Alice Avg: 88.75 Bob Avg: 67.50 Carol Avg: 91.50 David Avg: 81.25 Eve Avg: 71.25 Frank Avg: 87.50 Grace Avg: 91.25 Henry Avg: 79.00解析%-10s表示左对齐宽度 10 的字符串%6.2f表示宽度 6 精度 2 的浮点数。printf不像print那样自动换行需要手动添加\n。4. 模式匹配awk 的模式匹配是其核心特性之一支持多种匹配方式。4.1 BEGIN 和 END 块BEGIN块在处理输入前执行END块在处理完所有输入后执行awkBEGIN{print Start } {print $1} END{print End }students.txt输出结果 Start Tom Jerry Alice Bob Carol David Eve Frank Grace Henry End 4.2 字段值比较awk$2 85 {print $1, $2}students.txt输出结果Tom 90 Alice 88 Carol 95 Grace 92解析$2 85是一个表达式模式只有第 2 个字段值大于 85 的行才会执行{print $1, $2}动作。4.3 正则表达式匹配awk/ERROR/ {print}webapp.log输出结果2025-01-10 09:00:15 ERROR DatabaseConnection - Failed to connect to db:timeout 2025-01-10 09:01:30 ERROR NullPointerException - at com.app.UserService:line 45 2025-01-10 09:02:15 ERROR DatabaseConnection - Failed to connect to db:refused 2025-01-10 09:03:15 ERROR TimeoutException - Request timeout after 30s 2025-01-10 09:04:00 ERROR NullPointerException - at com.app.OrderService:line 784.4 对特定字段进行正则匹配使用~运算符对特定字段进行正则匹配awk$1 ~ /^2025/ {print $1, $2, $3}webapp.log|head-5输出结果2025-01-10 09:00:01 INFO 2025-01-10 09:00:15 ERROR 2025-01-10 09:00:30 INFO 2025-01-10 09:01:00 WARN 2025-01-10 09:01:30 ERROR4.5 范围模式使用逗号分隔两个模式匹配从第一个模式到第二个模式之间的所有行awk/INFO/,/ERROR/ {print NR, $3}webapp.log|head-10输出结果1 INFO 2 ERROR 3 INFO 4 WARN 5 ERROR 6 INFO 7 ERROR 8 INFO 9 WARN 10 ERROR4.6 复合条件awkNF 5 $2 80 {print $1, $2}students.txt输出结果Tom 90 Alice 88 Carol 95 Frank 85 Grace 92解析NF 5 $2 80组合了两个条件使用连接。awk 还支持||或和!非逻辑运算符可以构建复杂的匹配条件。5. 条件语句awk 支持if-else if-else条件判断语法与 C 语言一致。5.1 成绩等级判定awk{ total $2 $3 $4 $5 avg total / 4 if (avg 85) grade A else if (avg 75) grade B else if (avg 65) grade C else grade D printf %-10s %6.2f %s\n, $1, avg, grade }students.txt输出结果Tom 86.25 A Jerry 82.50 B Alice 88.75 A Bob 67.50 C Carol 91.50 A David 81.25 B Eve 71.25 C Frank 87.50 A Grace 91.25 A Henry 79.00 B解析awk 的if-else if-else语法与 C 语言完全一致。通过多级条件判断将平均分映射为字母等级这是数据处理中常见的分类操作。6. 循环语句awk 支持for、while和do-while三种循环。6.1 for 循环计算总分和平均分awk{ sum 0 for (i 2; i NF; i) sum $i printf %-10s Total: %4d Avg: %6.2f\n, $1, sum, sum/(NF-1) }students.txt输出结果Tom Total: 345 Avg: 86.25 Jerry Total: 330 Avg: 82.50 Alice Total: 355 Avg: 88.75 Bob Total: 270 Avg: 67.50 Carol Total: 366 Avg: 91.50 David Total: 325 Avg: 81.25 Eve Total: 285 Avg: 71.25 Frank Total: 350 Avg: 87.50 Grace Total: 365 Avg: 91.25 Henry Total: 316 Avg: 79.006.2 while 循环awk{ sum 0 i 2 while (i NF) { sum $i; i } print $1, sum }students.txt输出结果Tom 345 Jerry 330 Alice 355 Bob 270 Carol 366 David 325 Eve 285 Frank 350 Grace 365 Henry 3166.3 do-while 循环awkBEGIN { i 1 do { print i i } while (i 5) }输出结果1 2 3 4 56.4 break 和 continueawkBEGIN { for (i 1; i 10; i) { if (i 5) break if (i % 2 0) continue print i } }输出结果1 3解析break跳出循环continue跳过本次循环剩余语句。循环到i5时break终止循环偶数时continue跳过打印所以只输出了 1 和 3。7. 字符串函数awk 内置了丰富的字符串处理函数。函数说明示例length(s)返回字符串长度length(hello)→ 5substr(s, m, n)截取子串substr(hello, 2, 3)→ “ell”split(s, arr, sep)分割字符串到数组split(a,b,c, arr, ,)index(s, t)查找子串位置index(hello, ll)→ 3match(s, r)正则匹配match(abc123, /[0-9]/)sub(r, t, s)替换第一个匹配sub(/a/, x, aaa)→ “xaa”gsub(r, t, s)替换所有匹配gsub(/a/, x, aaa)→ “xxx”toupper(s)转大写toupper(abc)→ “ABC”tolower(s)转小写tolower(ABC)→ “abc”7.1 length() - 字符串长度awk{print $1, length($1)}students.txt输出结果Tom 3 Jerry 5 Alice 5 Bob 3 Carol 5 David 5 Eve 3 Frank 5 Grace 5 Henry 57.2 substr() - 截取子串awk{print substr($1, 1, 3)}students.txt输出结果Tom Jer Ali Bob Car Dav Eve Fra Gra Hen7.3 split() - 分割字符串awkBEGIN { n split(a,b,c,d,e, arr, ,) print Split into, n, parts for (i 1; i n; i) print arr[i] }输出结果Split into 5 parts a b c d e7.4 index() - 查找子串位置awkBEGIN { pos index(Hello World, World) print Position:, pos }输出结果Position: 77.5 match() - 正则匹配awkBEGIN { if (match(abc123def, /[0-9]/)) print Matched at, RSTART, length, RLENGTH }输出结果Matched at 4 length 3解析match()函数匹配成功后RSTART存储匹配的起始位置RLENGTH存储匹配的长度。这在提取复杂模式时非常有用。7.6 sub() 和 gsub() - 替换函数# sub() 只替换第一个匹配awk{str$0; sub(/ERROR/, [ERR], str); print str}webapp.log|head-5输出结果2025-01-10 09:00:01 INFO UserLogin - user:admin, ip:192.168.1.1 2025-01-10 09:00:15 [ERR] DatabaseConnection - Failed to connect to db:timeout 2025-01-10 09:00:30 INFO UserLogin - user:zhangsan, ip:192.168.1.2 2025-01-10 09:01:00 WARN MemoryUsage - Memory at 85% 2025-01-10 09:01:30 [ERR] NullPointerException - at com.app.UserService:line 45# gsub() 替换所有匹配awkBEGIN { str 2025-01-10 gsub(/-/, /, str) print str }输出结果2025/01/107.7 toupper() - 转大写awk{print toupper($1)}students.txt输出结果TOM JERRY ALICE BOB CAROL DAVID EVE FRANK GRACE HENRY8. 数组用法awk 支持关联数组associative array即数组下标可以是字符串这是 awk 最强大的特性之一。8.1 基本数组awkBEGIN { arr[1] one arr[2] two arr[3] three for (i 1; i 3; i) print arr[i] }输出结果one two three8.2 关联数组统计职位人数awk-F,{ count[$3] } END { for (pos in count) print pos, count[pos] }employees.txt输出结果manager 3 tester 2 developer 3解析count[$3]以职位名作为数组下标进行计数。for (key in array)遍历关联数组的所有键。这种模式在数据统计中极为常用。8.3 分组统计薪资awk-F,{ sum[$3] $4 count[$3] } END { for (pos in sum) printf %-12s Total: %6d Count: %d Avg: %8.2f\n, pos, sum[pos], count[pos], sum[pos]/count[pos] }employees.txt输出结果manager Total: 45000 Count: 3 Avg: 15000.00 tester Total: 17500 Count: 2 Avg: 8750.00 developer Total: 36000 Count: 3 Avg: 12000.008.4 数组映射转换使用数组实现映射表将职位名转换为缩写awk-F, BEGIN { split(manager:admin,developer:dev,tester:qa, pairs, ,) for (i in pairs) { split(pairs[i], kv, :) map[kv[1]] kv[2] } } { print $1, $2, map[$3], $4 }employees.txt输出结果1 zhangsan admin 15000 2 lisi dev 12000 3 wangwu dev 11000 4 zhaoliu qa 9000 5 tianqi admin 16000 6 zhouba dev 13000 7 wujiu qa 8500 8 zhengshi admin 14000解析在BEGIN块中构建映射表将 “manager” → “admin”、“developer” → “dev”、“tester” → “qa”。处理每行时用map[$3]查找对应的缩写。这是数据清洗中常见的编码转换操作。8.5 排序数组输出关联数组的for (key in array)遍历顺序是不确定的。如果需要排序输出可以手动实现awk-F,{ count[$3] } END { n 0 for (pos in count) { arr[n] pos } # 冒泡排序 for (i 0; i n; i) for (j i1; j n; j) if (arr[i] arr[j]) { t arr[i]; arr[i] arr[j]; arr[j] t } for (i 0; i n; i) print arr[i], count[arr[i]] }employees.txt输出结果developer 3 manager 3 tester 29. 多字段处理与分隔符9.1 指定字段分隔符awk-F,{print $1, $2, $3, $4}employees.txt输出结果1 zhangsan manager 15000 2 lisi developer 12000 3 wangwu developer 11000 4 zhaoliu tester 9000 5 tianqi manager 16000 6 zhouba developer 13000 7 wujiu tester 8500 8 zhengshi manager 140009.2 多字符分隔符使用正则表达式指定多个分隔符echoa:b,c:d,e|awk-F[:,]{for(i1; iNF; i) print i, $i}输出结果1 a 2 b 3 c 4 d 5 e解析-F[:,]将冒号和逗号都作为分隔符一行中的所有分隔符都会被识别将字符串切分为 5 个字段。9.3 -v 传递外部变量awk-vthreshold85{if($2 threshold) print $1, $2}students.txt输出结果Tom 90 Alice 88 Carol 95 Frank 85 Grace 929.4 处理带表头的 CSVawk-F,NR 1 {next} {print $2, $3, $4 * $5}sales.csv输出结果Laptop North 40000 Mouse South 2500 Keyboard East 4500 Monitor West 20000 Laptop South 24000 Mouse North 5000 Keyboard West 6750 Monitor East 16000 Laptop East 56000 Mouse West 4000解析NR 1 {next}跳过第一行表头$4 * $5计算数量乘以单价得到销售额。-v选项可以在 awk 程序外部传递变量使脚本更加灵活。10. 实际案例10.1 统计日志级别分布awk{ count[$3] } END { for (level in count) printf %-8s %d\n, level, count[level] }webapp.log输出结果WARN 2 ERROR 5 INFO 5解析用关联数组以日志级别第 3 字段为键统计出现次数。在生产环境中这是监控日志健康度的基本操作。10.2 学生成绩综合报表awkBEGIN { printf %-10s %6s %6s %6s %8s %s\n, Name, Max, Min, Total, Average, Grade print ------------------------------------------------------ } { max $2; min $2; total $2 for (i 3; i NF; i) { if ($i max) max $i if ($i min) min $i total $i } avg total / (NF - 1) if (avg 85) g A else if (avg 75) g B else if (avg 65) g C else g D printf %-10s %6d %6d %6d %8.2f %s\n, $1, max, min, total, avg, g }students.txt输出结果Name Max Min Total Average Grade ------------------------------------------------------ Tom 92 78 345 86.25 A Jerry 95 70 330 82.50 B Alice 92 85 355 88.75 A Bob 75 60 270 67.50 C Carol 95 88 366 91.50 A David 82 78 325 81.25 B Eve 75 68 285 71.25 C Frank 90 85 350 87.50 A Grace 95 88 365 91.25 A Henry 82 76 316 79.00 B解析这个案例综合运用了BEGIN块、for循环、if-else条件、printf格式化输出和数学计算生成了一个包含最高分、最低分、总分、平均分和等级的完整报表。10.3 销售数据按产品汇总awk-F,NR 1 { revenue $4 * $5 total[$2] revenue qty[$2] $4 count[$2] } END { printf %-10s %8s %8s %8s %12s\n, Product, Orders, Qty, AvgQty, TotalRevenue print ------------------------------------------------------------ for (p in total) printf %-10s %8d %8d %8.1f %12.2f\n, p, count[p], qty[p], qty[p]/count[p], total[p] }sales.csv输出结果Product Orders Qty AvgQty TotalRevenue ------------------------------------------------------------ Keyboard 2 75 37.5 11250.00 Laptop 3 15 5.0 120000.00 Monitor 2 18 9.0 36000.00 Mouse 3 230 76.7 11500.0010.4 销售数据按区域汇总awk-F,NR 1 { revenue $4 * $5 region_rev[$3] revenue region_cnt[$3] } END { printf %-8s %8s %14s\n, Region, Orders, TotalRevenue print ------------------------------------------ for (r in region_rev) printf %-8s %8d %14.2f\n, r, region_cnt[r], region_rev[r] }sales.csv输出结果Region Orders TotalRevenue ------------------------------------------ South 2 26500.00 East 3 76500.00 North 2 45000.00 West 3 30750.0010.5 提取并统计错误类型awk/ERROR/ { err_type[$4] count } END { print Total Errors:, count print print Error Breakdown: for (e in err_type) print , err_type[e], e }webapp.log输出结果Total Errors: 5 Error Breakdown: 1 TimeoutException 2 DatabaseConnection 2 NullPointerException解析先匹配包含ERROR的行以错误类型第 4 字段为键统计次数。结果清晰展示了错误总数和各类型错误的分布是运维排障的利器。10.6 查找平均分前三名学生awk{ total 0 for (i 2; i NF; i) total $i avg total / (NF - 1) avgs[NR] avg names[NR] $1 } END { # 按平均分降序排序 for (i 1; i NR; i) for (j i1; j NR; j) if (avgs[i] avgs[j]) { t avgs[i]; avgs[i] avgs[j]; avgs[j] t t names[i]; names[i] names[j]; names[j] t } print Top 3 Students by Average: for (i 1; i 3; i) printf %d. %-10s %6.2f\n, i, names[i], avgs[i] }students.txt输出结果Top 3 Students by Average: 1. Carol 91.50 2. Grace 91.25 3. Alice 88.7510.7 词频统计awk{ for (i 1; i NF; i) words[$i] } END { for (w in words) print words[w], w }webapp.log|sort-rn|head-10输出结果12 2025-01-10 12 - 5 INFO 5 ERROR 4 to 4 at 3 UserLogin 2 WARN 2 records 2 NullPointerException解析遍历每个字段用关联数组统计每个词的出现次数配合sort -rn按数值降序排列取前 10 个高频词。这是文本分析的基础操作。10.8 员工薪资统计报表awk-F,NR 1 { emp_count salary_sum $4 if ($4 max_sal) { max_sal $4; max_name $2 } if (min_sal 0 || $4 min_sal) { min_sal $4; min_name $2 } } END { printf Employee Salary Report\n printf \n printf Total Employees: %d\n, emp_count printf Average Salary: %.2f\n, salary_sum / emp_count printf Highest: %s (%d)\n, max_name, max_sal printf Lowest: %s (%d)\n, min_name, min_sal }employees.txt输出结果Employee Salary Report Total Employees: 7 Average Salary: 11928.57 Highest: tianqi (16000) Lowest: wujiu (8500)解析这个案例在一次遍历中同时统计了员工总数、薪资总和、最高薪资和最低薪资充分展示了 awk 在数据汇总方面的高效性。在实际生产中类似的报表生成是 awk 最典型的应用场景。总结本文在远程 Ubuntu 服务器上完整实操了 awk 的 17 个核心知识模块模块核心知识点应用场景工作模式pattern {action}、$N字段引用基本文本提取内置变量NR、NF、FS、OFS、FILENAME行号、字段数、分隔符控制printf%s、%d、%f格式化报表格式化输出模式匹配BEGIN/END、正则、比较、范围条件过滤条件语句if-else if-else数据分类分级循环语句for、while、do-while遍历字段、迭代计算字符串函数length、substr、split、sub、gsub字符串处理数组关联数组、分组统计、映射数据聚合、编码转换分隔符-F、-v、多分隔符CSV/TSV 处理实际案例日志分析、成绩统计、销售报表生产环境实战核心要点关联数组是 awk 最强大的特性下标可以是字符串天然适合分组统计BEGIN/END 块分别用于初始化和汇总输出是报表生成的标准模式printf比 print 更灵活能精确控制输出格式适合生成对齐的表格-F选项和FS 变量灵活控制字段分隔使 awk 能处理各种结构化数据-v选项可以在命令行传递变量使 awk 脚本参数化提高复用性awk 是完整的编程语言支持变量、条件、循环、函数、数组能完成复杂的数据处理任务sed vs awk 对比特性sedawk定位流编辑器数据处理语言擅长文本替换、删除、插入字段提取、统计计算编程能力有限完整变量、循环、数组典型场景批量修改配置文件日志分析、报表生成输出控制-npprint/printf分隔符行为单位字段为单位可自定义思考题如何使用 awk 计算一个文件中所有数值字段的总和与平均值awk 的关联数组与普通数组有什么区别如何实现按值排序输出如何使用 awk 同时处理多个文件并分别统计每个文件的行数awk BEGIN{FS,} {print $1}和awk -F, {print $1}有什么区别如何使用 awk 实现 SQL 的GROUP BY ... SUM(...)功能在处理大日志文件时awk 的性能优势体现在哪里与 Python/Java 相比如何如何使用 awk 的split()函数将一个字段进一步拆分为子字段编写一个 awk 脚本从 Nginx access log 中统计每个 IP 的访问次数和总流量按访问次数降序输出 Top 10。上一章回顾Shell脚本编程开发实战五文本处理三剑客之 sed 完全攻略 —— sed 以行为单位进行流编辑擅长文本的查找、删除、替换和插入操作。系列导航sed 和 awk 是 Shell 文本处理的核心技能建议结合 grep 一起学习掌握三剑客的组合使用将极大提升你在 Linux 环境下的数据处理效率。本文所有命令均在 Ubuntu 22.04 LTS (Kernel 6.8.0) 上真实执行输出结果为服务器实际返回。