awk
awk 是强大的文本处理工具,逐行读取输入,按字段分割后执行规则。
基本语法
bash
awk [选项] 'pattern { action }' file
awk [选项] -f script.awk file内置变量
| 变量 | 说明 |
|---|---|
$0 | 当前整行 |
$1 ~ $NF | 第 1 至最后一个字段 |
NF | 当前行字段数 |
NR | 当前行号(总行数) |
FNR | 当前文件内行号 |
FS | 输入字段分隔符(默认空格/Tab) |
OFS | 输出字段分隔符(默认空格) |
RS | 输入记录分隔符(默认换行) |
ORS | 输出记录分隔符(默认换行) |
FILENAME | 当前文件名 |
常用示例
打印指定字段
bash
# 打印每行第1、3字段
awk '{ print $1, $3 }' file.txt
# 以冒号分隔,打印用户名和 shell
awk -F: '{ print $1, $7 }' /etc/passwd模式匹配
bash
# 包含 "error" 的行
awk '/error/' file.txt
# 不包含 "error" 的行
awk '!/error/' file.txt
# 第3字段大于100的行
awk '$3 > 100' file.txt
# 行号范围(第5到第10行)
awk 'NR>=5 && NR<=10' file.txtBEGIN / END
bash
# 统计行数
awk 'BEGIN { count=0 } { count++ } END { print count }' file.txt
# 指定分隔符并打印表头
awk 'BEGIN { FS=":"; OFS="\t"; print "USER","SHELL" } { print $1,$7 }' /etc/passwd字段运算
bash
# 求第2列之和
awk '{ sum += $2 } END { print "Total:", sum }' file.txt
# 计算平均值
awk '{ sum += $1; count++ } END { printf "Avg: %.2f\n", sum/count }' file.txt条件与循环
bash
# if 判断
awk '{ if ($3 > 50) print $1, "high"; else print $1, "low" }' file.txt
# for 循环打印所有字段
awk '{ for(i=1; i<=NF; i++) print i, $i }' file.txt字符串处理
bash
# 字符串替换(第一个匹配)
awk '{ sub(/foo/, "bar"); print }' file.txt
# 全局替换
awk '{ gsub(/foo/, "bar"); print }' file.txt
# 字符串长度
awk '{ print length($0), $0 }' file.txt
# 截取子串 substr(str, start, len)
awk '{ print substr($1, 1, 3) }' file.txt
# 字段拆分 split(str, arr, sep)
awk '{ n=split($0, arr, ":"); for(i=1;i<=n;i++) print arr[i] }' file.txt输出格式化
bash
# printf 格式化
awk '{ printf "%-10s %5d\n", $1, $2 }' file.txt多文件 / 管道
bash
# 处理多个文件,按文件名分组
awk 'FNR==1 { print "--- File:", FILENAME }{ print }' file1.txt file2.txt
# 从命令输出读取
ps aux | awk '$3 > 1.0 { print $1, $2, $3 }'变量传入
bash
# 通过 -v 传入变量
awk -v threshold=100 '$2 > threshold { print $1 }' file.txt实用技巧
bash
# 去重(保留第一次出现)
awk '!seen[$0]++' file.txt
# 统计每个值出现次数
awk '{ count[$1]++ } END { for (k in count) print k, count[k] }' file.txt
# 打印两个模式之间的行(含边界)
awk '/START/,/END/' file.txt
# 删除空行
awk 'NF > 0' file.txt
# 反转字段顺序
awk '{ for(i=NF; i>=1; i--) printf "%s%s", $i, (i>1?OFS:ORS) }' file.txt