Skip to content

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.txt

BEGIN / 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