基础
运行 AWK
awk '{ print }' file.txt # print every line awk '{ print $1 }' file.txt # print first field awk -F: '{ print $1 }' /etc/passwd # custom delimiter awk -f script.awk file.txt # run from file cmd | awk '{ print $2 }' # pipe input
程序结构
awk 'pattern { action }'基本格式——模式匹配时执行 action
BEGIN { ... }在处理输入之前运行一次
END { ... }处理完所有输入后运行一次
无模式对每一行都执行 action
无 action默认 action 为 { print }
模式与动作
模式类型
awk '/error/' file.txt # regex match awk '$3 > 100' file.txt # comparison awk 'NR >= 5 && NR <= 10' file.txt # line range awk '/start/,/end/' file.txt # range pattern
模式参考
/regex/将行与正则表达式匹配
$1 ~ /pat/字段匹配正则
$1 !~ /pat/字段不匹配正则
expr1, expr2范围:从第一个匹配到第二个
expr1 && expr2逻辑与
expr1 || expr2逻辑或
!expr逻辑非
变量
内置变量
NR当前记录(行)编号
NF当前记录的字段数
FS输入字段分隔符(默认:空白)
OFS输出字段分隔符(默认:空格)
RS输入记录分隔符(默认:换行)
ORS输出记录分隔符(默认:换行)
FILENAME当前输入文件名
FNR当前文件中的记录编号
用户变量
awk '{ total += $1 } END { print total }' file.txt awk -v threshold=50 '$1 > threshold' file.txt awk 'BEGIN { count = 0 } /pat/ { count++ } END { print count }' file.txt
字段
字段访问
$0整行内容
$1, $2, ...第一、第二……字段
$NF最后一个字段
$(NF-1)倒数第二个字段
字段分隔符
awk -F, '{ print $2 }' data.csv # comma awk -F'\t' '{ print $1 }' data.tsv # tab awk 'BEGIN { FS = "[,:]" } { print $1 }' f # multi-char awk 'BEGIN { OFS = "," } { print $1, $3 }' f # output sep
控制流
条件与循环
awk '{ if ($1 > 50) print "high"; else print "low" }' f awk '{ for (i = 1; i <= NF; i++) print $i }' f awk '{ i = 1; while (i <= NF) { print $i; i++ } }' f awk '/skip/ { next } { print }' f # skip matching lines
控制语句
if (cond) { ... } else { ... }条件判断
for (i = 0; i < n; i++) { ... }C 风格 for 循环
for (key in array) { ... }遍历数组键
while (cond) { ... }while 循环
do { ... } while (cond)do-while 循环
next跳到下一条输入记录
exit停止处理,执行 END 块
函数
用户定义函数
awk 'function max(a, b) { return (a > b) ? a : b } { print max($1, $2) }' file.txt
数值函数
int(x)截断为整数
sqrt(x)平方根
sin(x), cos(x)三角函数
log(x), exp(x)自然对数与指数
rand()0 到 1 之间的随机浮点数
srand(seed)设置随机数种子
数组
关联数组
awk '{ count[$1]++ } END { for (k in count) print k, count[k] }' f awk '{ arr[NR] = $0 } END { for (i = NR; i >= 1; i--) print arr[i] }' f
数组操作
arr[key] = val设置元素
arr[key]获取元素(访问时自动创建)
key in arr判断键是否存在
delete arr[key]删除单个元素
delete arr删除整个数组
for (k in arr)遍历键(无序)
length(arr)元素数量(gawk)
字符串函数
字符串参考
length(s)字符串长度
substr(s, start, len)子串(从 1 开始计数)
index(s, target)target 在 s 中的位置(未找到返回 0)
split(s, arr, sep)将字符串拆分到数组
sub(pat, repl, s)替换第一个匹配
gsub(pat, repl, s)替换所有匹配
match(s, pat)正则匹配位置(设置 RSTART、RLENGTH)
tolower(s) / toupper(s)大小写转换
sprintf(fmt, ...)格式化字符串(类似 C printf)
字符串示例
awk '{ gsub(/old/, "new"); print }' f # sed-like replace awk '{ print toupper($0) }' f # uppercase all awk '{ print substr($0, 1, 40) }' f # truncate to 40
I/O
输出
awk '{ print $1, $2 }' f # space-separated awk '{ printf "%s,%d\n", $1, $2 }' f # formatted output awk '{ print $1 > "out.txt" }' f # redirect to file awk '{ print $1 >> "out.txt" }' f # append to file
I/O 参考
print带 ORS 输出(默认换行)
printf fmt, ...格式化输出(不自动换行)
print > file重定向到文件
print >> file追加到文件
print | cmd管道输出到命令
getline < file从文件读取一行
cmd | getline var将命令输出读入变量
close(file)关闭文件或管道
常用模式
单行命令
awk '{ sum += $1 } END { print sum }' f # sum column awk 'END { print NR }' f # count lines awk '!seen[$0]++' f # remove dupes awk 'NF' f # remove blanks awk '{ print NF }' f # fields per line
实用配方
CSV 转 TSVawk -F, 'BEGIN{OFS="\t"} {$1=$1; print}'
第 2 列求和awk '{ s += $2 } END { print s }'
前 N 行awk 'NR <= 10'(类似 head)
频次统计awk '{ c[$1]++ } END { for (k in c) print k, c[k] }'
区间提取awk '/BEGIN/,/END/'
打印第 N 列awk '{ print $N }'(N 替换为列号)