awk 命令 #
awk
是一个强大的文本处理语言,专为处理结构化文本数据而设计。它可以按行处理文本,将每行分割为字段,然后对这些字段执行操作。awk
名称来源于其创建者的姓氏首字母:Aho、Weinberger 和 Kernighan。
语法 #
awk [选项] '程序' 文件...
或
awk [选项] -f 程序文件 文件...
常用选项 #
选项 | 描述 |
---|---|
-F fs |
指定字段分隔符(默认为空格) |
-v var=value |
设置变量 |
-f file |
从文件中读取 awk 程序 |
-W |
设置兼容性或警告级别 |
awk 程序结构 #
BEGIN { 初始化操作 }
/模式/ { 对匹配模式的行执行的操作 }
END { 最终操作 }
所有部分都是可选的。
内置变量 #
变量 | 描述 |
---|---|
$0 |
当前记录(整行) |
$1, $2, ... |
当前记录的第 1、2、…个字段 |
NF |
当前记录的字段数 |
NR |
当前记录的行号 |
FNR |
当前文件中的行号 |
FS |
输入字段分隔符(默认为空格) |
RS |
输入记录分隔符(默认为换行符) |
OFS |
输出字段分隔符(默认为空格) |
ORS |
输出记录分隔符(默认为换行符) |
FILENAME |
当前输入文件名 |
ARGC |
命令行参数数量 |
ARGV |
命令行参数数组 |
常见用法 #
1. 打印整行 #
# 打印文件的所有行
awk '{print}' file.txt
# 等同于
awk '{print $0}' file.txt
2. 打印特定字段 #
# 打印每行的第1个字段
awk '{print $1}' file.txt
# 打印每行的第1和第3个字段
awk '{print $1, $3}' file.txt
# 自定义输出格式
awk '{print "First: " $1 ", Third: " $3}' file.txt
3. 使用自定义分隔符 #
# 使用冒号作为分隔符(适用于/etc/passwd文件)
awk -F: '{print $1}' /etc/passwd
# 使用多个字符作为分隔符
awk -F'[,:]' '{print $1, $2}' file.txt
4. 条件处理 #
# 只打印第3个字段大于100的行
awk '$3 > 100 {print $0}' file.txt
# 只打印包含"pattern"的行
awk '/pattern/ {print $0}' file.txt
# 组合条件
awk '$3 > 100 && /pattern/ {print $0}' file.txt
5. 使用 BEGIN 和 END 块 #
# 添加标题和总结
awk 'BEGIN {print "Report:"} {print $0} END {print "End of report."}' file.txt
# 计算总和
awk 'BEGIN {sum=0} {sum+=$1} END {print "Sum:", sum}' file.txt
6. 内置函数 #
# 转换为大写
awk '{print toupper($0)}' file.txt
# 计算长度
awk '{print length($0)}' file.txt
# 使用substr提取子字符串
awk '{print substr($1, 1, 3)}' file.txt
7. 格式化输出 #
# 格式化数字
awk '{printf "%.2f\n", $1}' file.txt
# 创建表格式输出
awk '{printf "%-10s %5d\n", $1, $2}' file.txt
8. 计算和统计 #
# 计算第1列的总和
awk '{sum += $1} END {print sum}' file.txt
# 计算第1列的平均值
awk '{sum += $1; count++} END {print sum/count}' file.txt
# 找出最大值
awk 'BEGIN {max = 0} $1 > max {max = $1} END {print max}' file.txt
9. 处理多个文件 #
# 处理多个文件,显示文件名
awk '{print FILENAME, $0}' file1.txt file2.txt
# 只处理特定文件中的行
awk 'FILENAME == "file1.txt" {print $0}' file1.txt file2.txt
10. 使用变量 #
# 在命令行设置变量
awk -v threshold=100 '$1 > threshold {print $0}' file.txt
# 在程序中设置变量
awk 'BEGIN {threshold = 100} $1 > threshold {print $0}' file.txt
11. 使用数组 #
# 计算每个单词的出现次数
awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(word in count) print word, count[word]}' file.txt
# 使用多维数组
awk '{data[$1][$2]++} END {for(i in data) for(j in data[i]) print i, j, data[i][j]}' file.txt
12. 控制流 #
# 使用if-else
awk '{if ($1 > 100) print "High"; else if ($1 > 50) print "Medium"; else print "Low"}' file.txt
# 使用循环
awk '{for(i=1;i<=NF;i++) print $i}' file.txt
实用示例 #
1. 分析日志文件 #
# 统计HTTP状态码
awk '{print $9}' access.log | sort | uniq -c | sort -nr
2. 处理 CSV 文件 #
# 处理CSV文件,打印特定列
awk -F, '{print $1, $3}' data.csv
3. 计算文件中的数字总和 #
awk '{for(i=1;i<=NF;i++) sum+=$i} END {print sum}' numbers.txt
4. 提取特定列并排序 #
awk '{print $3}' file.txt | sort -n
5. 删除重复行(类似于 uniq) #
awk '!seen[$0]++' file.txt
6. 计算文件的行数、字数和字符数(类似于 wc) #
awk 'BEGIN {lines=0; words=0; chars=0} {lines++; words+=NF; chars+=length($0)+1} END {print lines, words, chars}' file.txt
7. 替换文本(类似于 sed) #
awk '{gsub(/old/, "new"); print}' file.txt
内置函数 #
函数 | 描述 |
---|---|
length(str) |
返回字符串长度 |
substr(str, start, len) |
返回子字符串 |
toupper(str) |
转换为大写 |
tolower(str) |
转换为小写 |
index(str, substr) |
返回子字符串的位置 |
match(str, regex) |
正则表达式匹配 |
split(str, arr, sep) |
分割字符串到数组 |
gsub(regex, repl, str) |
全局替换 |
sub(regex, repl, str) |
替换第一次匹配 |
sprintf(fmt, expr) |
格式化字符串 |
rand() |
返回 0 到 1 之间的随机数 |
int(num) |
取整 |
提示 #
- awk 是按行处理文本的,默认以空格或制表符作为字段分隔符
- 使用单引号包围 awk 程序可以防止 shell 解释特殊字符
- 使用
-F
选项可以指定自定义的字段分隔符 - 在 awk 中,变量不需要声明就可以使用
- awk 支持关联数组(类似于哈希表或字典)
- 使用
next
语句可以跳过当前记录的处理 - 使用
exit
语句可以提前结束程序 - awk 支持正则表达式模式匹配
- 对于复杂的 awk 程序,可以将其保存在文件中,然后使用
-f
选项执行 - awk 是图灵完备的语言,可以用来编写复杂的程序