1 | awk ' 程序 ' 文件名 |
1 | 程序: |
awk
一次一行地读文件名中的输入,依次将每行与每个模式相比较,对每个与行相匹配的模式,执行其对应的操作。
1 | awk `/regex/ { print }` 文件名 |
省略动作,默认动作是打印相匹配的行
1 | awk '/regex/' 文件名 |
省略模式,被作用到任何输入行
1 | awk '{ print }' 文件名 |
从一个文件提交程序
1 | awk -f 命令文件 文件名 |
字段 $1, $2, ..., $NF
NF
是一个变量,被设置为字段的个数。
1 | du -a | awk '{ print $2 }' |
分隔符可以不是空白,-F
指定
1 | sed 3q /etc/passwd | awk -F: '{ print $1 }' |
打印内置变量 NR
是当前输入记录或行的总数。 $0
是整个输入行,未加更改。
1 | awk '{ print NR, $0}' |
printf
控制输出格式
1 | awk '{ printf "%4d %s\n", NR, $0 }' |
模式
1 | awk -F: '$2 == ""' /etc/passwd |
$2 == ""
$2 ~ /^$/
$2 !~ /./
lenght($2) == 0
1 | !($2 == "") |
1 | date | awk '{ print substr($4, 1, 5) }' |
BEGIN 与 END 模式
BEGIN
在第一个输入行之前就被执行:可以用 BEGINi
模式初始化变量,打印标题头或通过指定变量 FS
设置字段分隔符:
1 | awk 'BEGIN { FS = ":" } $2 == "" ' /etc/passwd |
END
在处理完最后一行后执行:
1 | awk 'END { print NR }' |
算术运算与变量
求第一列中所有数字之和 / 平均数
1 | { s = s + $1 } # 不必考虑初始化问题 |
计算文件页数,每页 66 行
1 | wc $* | |
字符串变量被初始化为空字符串。
1 | 内置变量 说明 |
控制流
example: 查找相邻的、成对的、完全相同的单词
1 | awk ' |
数组
example: 将每个输入行收集到单个数组元素中,以行数为索引,然后以逆序将其打印输出
1 | awk ' |
n = split(s, arr, seq)
将字符串 s 分成若干字段,并把这些字段分别保存在数组 arr 从 1 至 n 的元素中。若提供了分隔符字符 seq,则使用它;否则,使用 FS 的当前值。
1 | sed 1q /etc/passwd | awk '{ |
awk 的内置函数
内置函数 | 说明 |
---|---|
cons(expr) | expr 的余弦 |
exp(expr) | expr 的指数 |
Getline() | 读入下一个输入行,若是文件尾,则返回 0; 否则返回 1 |
index(string, substr) | string 中字符串 substr 的位置,若不存在,则返回 0 |
int(expr) | expr 的整数部分 |
lenght(s) | 字符串 s 的长度 |
log(expr) | expr 的自然对数 |
sin(expr) | expr 的正弦 |
Split(s, a, c) | 以 c 为分隔符将 s 分隔至 a[1],...,a[n]返回 n |
sprintf(fmt,...) | 根据格式 fmt 格式化 |
substr(s, m, n) | 起始于位置 m 的字串 s 的 n 个字符的子串 |
关联数组 1
2
3
4
5
6
7
8
9
10
11
12
13 { sum[$1] += $2 }
END {
for (name in sum)
print name, sum[name]
}
awk ' {
for (i = 1; i <= NF; i++)
num[$i]++
}
END {
for (word in num)
print word, num[word]
} ' $*
字符串
example: 将较长的行调整为 80 列
1 | awk ' |
与 shell 的交互作用
1 | awk '{ print $'$1' }' |
example: 对 n 个列中的每个列分别单独求和,然后再将各列之和相加
1 | awk ' |
基于 awk 的日历服务
calendar: version 3 -- today and tomorrow
1 | awk < $HOME/calendar ' |