一、内置函数详解
1. 数值函数
1 2 3 4 5 6 7 8 9 10
| awk 'BEGIN { print sqrt(16) print int(3.7) print rand() print srand() print log(10) print exp(2) }'
|
2. 字符串函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| awk 'BEGIN { str = "Hello World" print length(str) print substr(str, 1, 5) print substr(str, 7) print index(str, "World") print match(str, /W& print sub(/World/, "AWK", str) print gsub(/l/, "L", str) split("a,b,c", arr, ",") for(i in arr) print arr& }'
|
3. 时间函数
1 2 3 4 5 6 7
| awk 'BEGIN { print systime() print strftime("%Y-%m-%d") print strftime("%H:%M:%S", systime()) }'
|
4. 其他实用函数
1 2 3 4 5 6
| # 系统函数 awk 'BEGIN { print system("echo Hello") # 执行系统命令 print getline # 从输入读取下一行 }'
|
二、自定义函数
1. 基本语法
1 2 3 4 5
| function 函数名(参数列表) { 函数体 return 返回值 }
|
2. 实际示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| awk ' function avg(arr, n) { sum = 0 for(i = 1; i <= n; i++) { sum += arr& } return sum / n }
{ scores& } END { print "平均分:", avg(scores, NR) }' students.txt
|
1 2 3 4 5 6 7 8 9 10
| awk ' function format_name(first, last) { return toupper(substr(first,1,1)) substr(first,2) " " toupper(last) }
{ print format_name($1, $2) }' names.txt
|
三、正则表达式进阶
1. 正则表达式操作符
1 2 3 4 5 6 7 8
| awk '/^[0-9]+$/ {print "纯数字:", $0}' file.txt # 行首到行尾都是数字 awk '/\.[a-zA-Z]{3,4}$/ {print "文件:", $0}' file.txt # 匹配文件扩展名
awk '{gsub(/[0-9]+/, "NUM"); print}' file.txt # 替换所有数字为NUM awk '{sub(/^.*@/, ""); print}' emails.txt # 去掉邮箱前缀
|
2. match函数的高级用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| awk '{ if(match($0, /& date = substr($0, RSTART, RLENGTH) print "找到日期:", date } }' logs.txt
awk '{ if(match($0, /(& print "年:", arr& } }' logs.txt
|
四、多维数组处理
1. 模拟多维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| awk '{ matrix& matrix& matrix& } END { for(row = 1; row <= NR; row++) { for(col = 1; col <= 3; col++) { printf "%s\t", matrix& } print "" } }' data.txt
|
2. 关联数组的复杂应用
1 2 3 4 5 6 7 8 9 10 11 12 13
| awk '{ user = $1 date = $2 count& } END { for(key in count) { split(key, parts, ",") print parts& } }' user_log.txt
|
五、getline的高级用法
1. 从文件读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # 读取配置文件 awk ' BEGIN { while((getline line < "config.txt") > 0) { if(line ~ /=/) { split(line, kv, "=") config[kv[1]] = kv[2] } } close("config.txt") } { print $1, config["prefix"] $2 }' data.txt
|
2. 从管道读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| awk ' BEGIN { cmd = "ls -l" while((cmd | getline) > 0) { if(NF > 8) files[$NF] = $5 # 文件名和大小 } close(cmd) } { if($1 in files) { print $1, files[$1] } }' file_list.txt
|
六、输入输出控制
1. 输出重定向
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 输出到不同文件 awk '{ if($2 >= 60) { print $0 > "pass.txt" } else { print $0 > "fail.txt" } } END { close("pass.txt") close("fail.txt") }' scores.txt
|
2. 格式化输出控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 控制输出格式 awk 'BEGIN { OFS = "\t" # 输出字段分隔符 ORS = "\n---\n" # 输出记录分隔符 } { print $1, $2, $3 }' data.txt
# printf的高级用法 awk '{ printf "%-10s %8.2f %5d\n", $1, $2, $3 }' sales.txt
|
七、错误处理与调试
1. 错误检查
1 2 3 4 5 6 7 8 9
| # 检查getline返回值 awk '{ if((getline line) <= 0) { print "读取失败或文件结束" > "/dev/stderr" exit 1 } print line }'
|
2. 调试技巧
1 2 3 4 5 6 7 8 9
| awk '{ print "DEBUG: processing line", NR, "with", NF, "fields" > "/dev/stderr" }' data.txt
awk -d 'BEGIN {var=1; print var}'
|
八、性能优化技巧
1. 避免重复计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| awk '{ if(length($1) > 10) { # 每次都计算长度 print $1 } }'
awk '{ len = length($1) # 只计算一次 if(len > 10) { print $1 } }'
|
2. 合理使用正则
1 2 3 4 5 6
| awk '$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/'
awk 'substr($0,1,19) ~ /^[0-9 :-]+$/'
|
九、实用中级示例
1. 日志分析脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
BEGIN { FS = " " print "IP地址\t\t访问次数\t流量总计" } { ip = $1 bytes = ($10 == "-" ? 0 : $10) count& total_bytes& } END { for(ip in count) { printf "%-15s\t%8d\t%10d\n", ip, count& } }
|
2. 数据透视表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| # 生成销售数据透视表 awk ' BEGIN { FS = "," print "产品\t一月\t二月\t三月\t总计" } NR > 1 { product = $1 month = $2 sales = $3 monthly[product,month] += sales total[product] += sales } END { months["一月"] = "一月"; months["二月"] = "二月"; months["三月"] = "三月" for(product in total) { printf "%s", product for(month in months) { printf "\t%d", monthly[product,month] } printf "\t%d\n", total[product] } }' sales.csv
|
3. 配置文件解析器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # 解析INI格式配置文件 awk ' BEGIN { section = "global" } /^\[ sub(/^\[ sub(/\]$/, "") section = $0 next } /^[ split($0, kv, "=") config[ } END { for(key in config) { print key " = " config[ } }' config.ini
|
十、GNU AWK 扩展功能
1. 高精度计算
1 2 3 4 5 6
| # 使用 -M 选项进行高精度计算 awk -M 'BEGIN { print 1/3 # 精确到小数点后多位 print 2^100 # 大数计算 }'
|
2. 包含文件
1 2 3 4 5 6 7 8 9 10 11
| # functions.awk function square(x) { return x * x } function cube(x) { return x * x * x }
# main.awk @include "functions.awk" BEGIN { print square(5) # 25 print cube(3) # 27 }
|
3. 扩展库使用
1 2 3 4 5
| awk -l json 'BEGIN { # JSON处理功能 }'
|
这些中级内容涵盖了 AWK 的核心中高级功能,掌握后可以处理更复杂的文本处理任务。
相关阅读