文档首页> 互联网资讯> linux awk文本处理:从字段提取到日志统计

linux awk文本处理:从字段提取到日志统计

发布时间:2026-09-02 02:26       

linux awk

awk 是 Linux / Unix 系统中非常强大的文本处理工具,常用于日志分析、数据清洗、字段提取、统计汇总、报表生成等场景。它既可以作为命令行工具快速处理文本,也可以编写较复杂的脚本完成结构化数据处理。

一、awk 的基本语法

awk 的基本格式如下:

awk '条件 { 动作 }' 文件名

也可以写成:

awk 'pattern { action }' file

其中:

  • pattern:匹配条件,可以省略。
  • action:满足条件后执行的动作,例如打印、计算、替换等。
  • file:要处理的文件。

例如,打印文件每一行:

awk '{ print }' test.txt

{ print } 是动作,表示对每一行执行打印操作。

二、按字段处理数据

awk 默认以空白字符作为分隔符,包括空格、Tab 等。每一行会被自动拆分成多个字段:

变量 含义
$0 当前整行
$1 第 1 个字段
$2 第 2 个字段
$3 第 3 个字段
$NF 最后一个字段
NF 当前行字段数量
NR 当前处理的总行号

例如,查看 /etc/passwd 文件中的用户名:

awk -F: '{ print $1 }' /etc/passwd

这里 -F: 表示使用冒号 : 作为字段分隔符。

也可以这样写:

awk 'BEGIN { FS=":" } { print $1 }' /etc/passwd

三、打印指定字段

假设有一个文件 students.txt

Tom 90 85 88
Jerry 76 92 80
Alice 95 88 91

打印每行第 1 列和第 2 列:

awk '{ print $1, $2 }' students.txt

输出:

Tom 90
Jerry 76
Alice 95

如果想自定义输出分隔符,可以使用 OFS

awk 'BEGIN { OFS="|" } { print $1, $2 }' students.txt

输出:

Tom|90
Jerry|76
Alice|95

四、条件过滤

awk 可以根据字段内容进行过滤。

例如,只打印第 2 列大于 80 的行:

awk '$2 > 80 { print $0 }' students.txt

也可以打印满足条件的姓名和分数:

awk '$2 > 80 { print $1, $2 }' students.txt

多个条件可以组合:

awk '$2 > 80 && $3 > 85 { print $1 }' students.txt

含义是:第 2 列大于 80,并且第 3 列大于 85。

五、统计计算

awk 很适合做统计。例如统计学生总分:

awk '{ sum = $2 + $3 + $4; print $1, sum }' students.txt

如果要统计所有学生第 2 列的总分和平均值:

awk '{ sum += $2; count++ } END { print "sum=", sum, "avg=", sum/count }' students.txt

其中:

  • sum += $2:累加第 2 列。
  • count++:统计行数。
  • END:在所有行处理完成后执行。

六、BEGIN 和 END 的作用

awk 中有两个常用特殊代码块:

1. BEGIN

BEGIN 在处理文件内容之前执行,常用于初始化变量、设置分隔符。

awk 'BEGIN { FS=","; OFS="|" } { print $1, $2 }' data.csv

2. END

END 在所有内容处理完成后执行,常用于输出统计结果。

awk 'END { print "总行数:", NR }' test.txt

七、字符串处理

awk 支持常见的字符串操作,例如替换、分割、匹配等。

1. 替换字符串

将字段中的 abc 替换为 xyz

awk '{ gsub(/abc/, "xyz"); print }' test.txt

gsub 表示全局替换,会替换所有匹配内容。

如果只替换第一个匹配项,可以使用 sub

awk '{ sub(/abc/, "xyz"); print }' test.txt

2. 字符串分割

使用 split 可以按指定分隔符拆分字符串:

awk '{ split($0, arr, ","); print arr[1], arr[2] }' data.csv

八、正则表达式匹配

awk 支持正则表达式,常用于日志分析。

例如,查找包含 error 的行:

awk '/error/ { print }' app.log

查找第 1 列以 user 开头的行:

awk '$1 ~ /^user/ { print }' data.txt

查找第 1 列不以 user 开头的行:

awk '$1 !~ /^user/ { print }' data.txt

常见符号:

符号 含义
^ 匹配开头
$ 匹配结尾
. 匹配任意单个字符
* 匹配前一个字符多次
+ 匹配前一个字符一次或多次
? 匹配前一个字符零次或一次
[] 匹配字符集合

九、格式化输出

awk 可以使用 printf 进行格式化输出。

例如:

awk '{ printf "%-10s %5d\n", $1, $2 }' students.txt

说明:

  • %-10s:字符串左对齐,宽度为 10。
  • %5d:数字宽度为 5。
  • \n:换行。

格式化输出常用于生成整齐的报表。

十、处理 CSV 文件

处理简单 CSV 文件时,可以使用逗号作为分隔符:

awk -F, '{ print $1, $3 }' data.csv

例如 data.csv

name,age,city
Tom,20,Beijing
Jerry,18,Shanghai

打印姓名和城市:

awk -F, 'NR > 1 { print $1, $3 }' data.csv

NR > 1 表示跳过表头。

十一、统计日志访问次数

假设日志格式如下:

192.168.1.1 - - [date] "GET /index.html HTTP/1.1" 200
192.168.1.2 - - [date] "GET /api HTTP/1.1" 200
192.168.1.1 - - [date] "GET /home HTTP/1.1" 404

统计每个 IP 出现次数:

awk '{ count[$1]++ } END { for (ip in count) print ip, count[ip] }' access.log

这里使用了数组 count

count[$1]++

表示以 IP 地址作为数组下标进行计数。

如果想按访问次数排序,可以结合 sort

awk '{ count[$1]++ } END { for (ip in count) print count[ip], ip }' access.log | sort -nr

十二、awk 常见命令示例

查看某列最大值:

awk 'BEGIN { max = 0 } { if ($2 > max) max = $2 } END { print max }' data.txt

统计文件总行数:

awk 'END { print NR }' file.txt

打印第 10 行:

awk 'NR == 10' file.txt

打印第 3 到第 8 行:

awk 'NR >= 3 && NR <= 8' file.txt

打印包含指定关键字的行号:

awk '/error/ { print NR, $0 }' app.log

十三、使用注意事项

  1. 字段分隔符要设置正确
    如果文件使用逗号、冒号、Tab 分隔,需要提前用 -FFS 设置。

  2. 注意引号使用
    在 Shell 中,awk 脚本通常使用单引号包裹,避免 Shell 解释特殊字符。

  3. 变量名不要和字段冲突
    awk 中的变量名应清晰,避免与 $1$2 等字段混淆。

  4. 处理大数据时尽量只遍历一次
    awk 是流式处理工具,适合逐行读取,效率较高。

  5. 复杂逻辑可写成 awk 脚本文件
    如果命令太长,可以保存为 .awk 文件,提高可维护性。

例如:

awk -f script.awk data.txt

script.awk 内容示例:

BEGIN { FS="," }
NR > 1 { print $1, $3 }

总结

awk 是 Linux 中非常实用的文本处理工具,核心特点是按行读取、按字段分析,并通过条件和动作完成过滤、计算、替换和统计。无论是处理日志、CSV 数据,还是生成报表,awk 都能用简洁的命令完成复杂任务。掌握 awk 的基本语法、字段变量、条件过滤、数组统计和格式化输出,就能大幅提升 Linux 命令行下的数据处理效率。