AWK 内置函数详解:从简单到巧妙的实际案例
提到 AWK,我们很容易想到它的字段处理功能,比如提取第几列、按行处理等。其实,AWK 的内置函数才是真正的灵魂!无论是字符串操作、数学计算,还是时间处理,AWK 都能通过这些内置函数展现出强大的数据处理能力。今天我们就来聊聊 AWK 内置函数的妙用,并通过实际案例,让你轻松上手。
1. 字符串处理函数
AWK 的字符串函数非常强大,用于文本处理再合适不过了。
1.1 length()
length() 用来计算字符串或行的长度。
例子:统计每行长度
awk '{print "Line:", $0, "Length:", length($0)}' file.txt输出:
Line: Hello World Length: 11
Line: AWK is great Length: 13更实用的场景:筛选长度大于 20 的行
awk 'length($0) > 20' file.txt这会过滤出所有长度大于 20 的行。
1.2 substr(string, start, length)
substr() 用来从字符串中提取子字符串。
例子:提取每行的前 5 个字符
awk '{print substr($0, 1, 5)}' file.txt如果 file.txt 内容如下:
HelloWorld
AWK is amazing输出:
Hello
AWK i实际案例:从日志中提取时间部分
假设有一个日志文件 access.log:
192.168.1.1 - - [10/Jan/2025:14:00:01] "GET /index.html HTTP/1.1" 200 512
192.168.1.2 - - [10/Jan/2025:14:05:01] "POST /login HTTP/1.1" 200 256提取日志中的时间:
awk '{print substr($4, 2)}' access.log这里的 substr($4, 2) 从第 4 列([10/Jan/2025:14:00:01])中跳过第一个字符 [,提取时间。
输出:
10/Jan/2025:14:00:01
10/Jan/2025:14:05:011.3 index(string, substring)
index() 返回子字符串在主字符串中的起始位置,如果不存在则返回 0。
例子:检查是否包含某单词
awk 'index($0, "error") {print NR, $0}' log.txt这会打印出包含单词 “error” 的行号和内容。
1.4 gsub(r, s [, t])
gsub() 是全局替换函数,将字符串 r 替换为 s。
例子:将文件中的 TAB 替换为空格
awk '{gsub("\t", " "); print}' file.txt实际案例:统一日期格式
将文件中的日期从 YYYY/MM/DD 转换为 YYYY-MM-DD:
awk '{gsub(/[0-9]{4}\/[0-9]{2}\/[0-9]{2}/, gensub("/", "-", "g")); print}' dates.txt2. 数学函数
AWK 的数学函数让我们可以在文本处理中轻松完成统计和计算任务。
2.1 int(x)
int() 返回 x 的整数部分(向下取整)。
例子:对成绩取整
awk '{print $1, int($2)}' scores.txt2.2 rand() 和 srand(seed)
rand()生成 0 到 1 的随机数。srand(seed)设置随机种子。
例子:生成 10 个随机数
awk 'BEGIN {srand(); for (i=1; i<=10; i++) print rand()}'实际案例:随机抽取一行数据
awk 'BEGIN {srand()} rand() < 0.1 {print $0}' file.txt2.3 sqrt(x)
sqrt() 返回 x 的平方根。
例子:计算平方根
awk '{print $1, sqrt($2)}' data.txt2.4 sin(x) 和 cos(x)
sin() 和 cos() 用来计算正弦和余弦值,x 的单位为弧度。
例子:生成简单的正弦波表
awk 'BEGIN {for (i=0; i<=360; i+=30) print i, sin(i * 3.14159 / 180)}'3. 时间和日期函数
3.1 systime()
systime() 返回当前时间的时间戳(1970 年 1 月 1 日以来的秒数)。
例子:打印当前时间戳
awk 'BEGIN {print systime()}'3.2 strftime(format, timestamp)
strftime() 根据格式化字符串将时间戳转换为可读时间。
例子:打印当前时间
awk 'BEGIN {print strftime("%Y-%m-%d %H:%M:%S", systime())}'4. 结合案例
案例 1:统计日志中不同状态码的数量
假设你的 access.log 文件如下:
192.168.1.1 - - [10/Jan/2025:14:00:01] "GET /index.html HTTP/1.1" 200 512
192.168.1.2 - - [10/Jan/2025:14:05:01] "POST /login HTTP/1.1" 404 256
192.168.1.3 - - [10/Jan/2025:14:10:01] "GET /home.html HTTP/1.1" 200 1024统计每种状态码的数量:
awk '{codes[$9]++} END {for (code in codes) print code, codes[code]}' access.log输出:
200 2
404 1案例 2:提取 CSV 文件中特定列的子字符串
假设你有一个 CSV 文件 users.csv:
1,JohnDoe,2025-01-10
2,AliceSmith,2025-01-11
3,BobBrown,2025-01-12提取用户名的前 4 个字符:
awk -F, '{print $2, substr($2, 1, 4)}' users.csv输出:
JohnDoe John
AliceSmith Alic
BobBrown Bob总结
AWK 的内置函数让我们能够高效地处理各种复杂的文本数据任务。无论是字符串操作、数学计算还是时间处理,AWK 都表现得游刃有余。如果你觉得今天的内容有帮助,赶快试试这些例子吧!当然,如果你有其他好用的技巧,欢迎留言,我们一起交流!










