一、准备工作
在当前文件夹创建employee.txt
文件,作为数据来源
1. employee.txt
01 ian 20000
02 alex 30000
03 lex 15000
04 ash 43000
05 bob 21000
06 faker 20000
07 boss 99999
二、一个简单的例子
打印第二列的数据
awk '{print $2}' employee.txt
# boss
# lex
# ian
# alex
# van
# bob
# john
# levin
# ash
或者是通过读取流的方式
cat employee.txt | awk '{print $2}'
# boss
# lex
# ian
# alex
# van
# bob
# john
# levin
# ash
除了读取文件以外,一般都是通过第二种,即读取流的方式,因为*nix
中流更常见
注意awk '{print $2}'
中的单引号不要打成了双引号。
对整个语句进行拆分:
awk
: 命令名称'{print $2}'
: 单引号包着的部分可以理解为awk
语言的代码(awk实际上是一门编程语言)。awk
是按行执行的,每到一行就会执行{}
里边的代码。print $2
,表示打印当前行的第二列,所以整个语句{print $2}
表示打印每一行的第二列,所以最终结果就是只把第二列打印了出来。
三、将awk
代码放入文件中
除了上面的命令行模式外,awk
还支持从文件中读取处理的代码
- 创建
format
文件,内容如下
{
print $2
}
# 写成单行的 {print $2} 也行
- 执行命令
awk -f format employee.txt
# boss
# lex
# ian
# alex
# van
# bob
# john
# levin
# ash
四、还可以写成shebang
风格的脚本
- 创建
format.awk
文件,内容如下
#! /usr/bin/awk -f
{
print $2
}
- 给
format.awk
可执行权限
chmod a+x format.awk
- 执行
./format.awk employee.txt
# boss
# lex
# ian
# alex
# van
# bob
# john
# levin
# ash
五、打印出所有数据(但是没有实际意义)
print
无参数打印每一行的所有列
awk '{print}' employee.txt
# 01 ian 20000
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 05 bob 21000
# 06 faker 20000
# 07 boss 99999
$0
为整行
awk '{print $0}' employee.txt
# 01 ian 20000
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 05 bob 21000
# 06 faker 20000
# 07 boss 99999
使用后面将会讲到的正则,不给予匹配条件
awk '//' employee.txt
三、打印第一列和第三列
awk '{print $1, $3}' employee.txt
四、格式化打印
awk '{printf "%d %-8s %-8d\n", $1, $2, $3}' employee.txt
# 1 ian 20000
# 2 alex 30000
# 3 lex 15000
# 4 ash 43000
# 5 bob 21000
# 6 faker 20000
# 7 boss 99999
五、使用BEGIN
增加表头
BEGIN{}
里边放的内容只会在开始前执行一次,所以可以用来输出表头之类的数据
1. format.awk
#! /usr/bin/awk -f
BEGIN{ printf "%-2s %-8s %-8s\n", "id", "name", "salary" }
{ printf "%-2d %-8s %-8sn", $1, $2, $3 }
2. 执行 ./format.awk employee.txt
$ ./format.awk employee.txt
# id name salary
# 1 ian 20000
# 2 alex 30000
# 3 lex 15000
# 4 ash 43000
# 5 bob 21000
# 6 faker 20000
# 7 boss 99999
六. 汇总 (END)
END{}
里边的代码只会在最后一行处理完后执行
1. format.awk
#! /usr/bin/awk -f
BEGIN{ printf "%-2s %-8s %-8s\n", "id", "name", "salary" }
{ printf "%-2s %-8s %-8s\n", $1, $2, $3, total_salary += $3 }
END{ printf "total salary is %.2f", total_salary }
2. 执行 ./format.awk employee.txt
$ ./format.awk employee.txt
# id name salary
# 01 ian 20000
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 05 bob 21000
# 06 faker 20000
# 07 boss 99999
# total salary is 248999.00%
七、打印行号
awk '{print NR, $0}'
# 1 01 ian 20000
# 2 02 alex 30000
# 3 03 lex 15000
# 4 04 ash 43000
# 5 05 bob 21000
# 6 06 faker 20000
# 7 07 boss 99999
八、打印每一行有多少列
awk '{print NF, $0}'
# 3 01 ian 20000
# 3 02 alex 30000
# 3 03 lex 15000
# 3 04 ash 43000
# 3 05 bob 21000
# 3 06 faker 20000
# 3 07 boss 99999
九、条件打印
1. 打印第一行
awk 'NR == 1 {print}' employee.txt
# 01 ian 20000
2. 打印薪资(第三列)大于 30000 的行
awk '$3 > 30000 {print}' employee.txt
# 04 ash 43000
# 07 boss 99999
3. 打印第 2 列中字符长度大于 3 的行
awk 'length($2) > 3' employee.txt
# 02 alex 30000
# 06 faker 20000
# 07 boss 99999
4. 打印除了第一行的所有行
awk 'NR > 1 {print}' employee.txt
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 05 bob 21000
# 06 faker 20000
# 07 boss 99999
5. 打印第一行和第三行
awk 'NR == 1 || NR == 3 {print}' employee.txt
# 01 ian 20000
# 03 lex 15000
6. 打印最后一行
$0 在END
块中已经获取不到了,所以要在之前保存下来
awk '{last = $0} END{print last}' employee.txt
十、传递变量
awk -v name=ian '$2 == name {print}' employee.txt
# 01 ian 20000
十一、查找
1. 查找所有列中包含 2 的记录
awk '/2/' employee.txt
# 01 ian 20000
# 02 alex 30000
# 05 bob 21000
# 06 faker 20000
上面例子相当于 awk '/2/ {print} employee.txt'
2. 查找第三列中包含 2 的记录
awk '$3 ~ /2/' employee.txt
# 01 ian 20000
# 05 bob 21000
# 06 faker 20000
3. 查找第三列中不包含 2 的记录
awk '$3 !~ /2/' employee.txt
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 07 boss 99999
4. 查找第二列中 a 开头的记录
awk '$2 ~ /^a/' employee.txt
# 02 alex 30000
# 04 ash 43000
5. 查找第二列中 x 结尾的记录
awk '$2 ~ /x$/' employee.txt
# 02 alex 30000
# 03 lex 15000
6. 查找第二列中包含 lex 或 ian 的行
awk '/lex|ian/' employee.txt
# 01 ian 20000
# 02 alex 30000
# 03 lex 15000
7. 查找第二列中不是 a 开头并包含 lex 的行
awk '/[^a]lex/' employee.txt
# 03 lex 15000
十二、数组
1. 基本使用
awk 'BEGIN{
arr["first"] = "apple"
arr["second"]="orange"
print arr["first"]
print arr["second"]
}'
# apple
# orange
2. 删除一个元素
awk 'BEGIN{
arr["first"] = "apple"
arr["second"] = "orange"
arr["third"] = "fruit"
delete arr["third"]
print arr["first"]
print arr["second"]
}'
# apple
# orange
#
流程语句
awk '{
if( $3 > 25000 ){
print $0
}
else{
print "-------------"
}
}' employee.txt
# -------------
# 02 alex 30000
# -------------
# 04 ash 43000
# -------------
# -------------
# 07 boss 99999
awk '{
if( $3 < 20000 ){
print "low"
}
else if( $3 >= 20000 && $3 < 30000 ){
print "normal"
}
else{
print "high"
}
}' employee.txt
# normal
# high
# low
# high
# normal
# normal
# high
内置函数
1. 字符串替换 gsub
有一天,boss 说 ian 不用干了,所以工资又回到 boss 手中
awk '{gsub("ian", "boss", $2)} {print}' employee.txt
# 01 boss 20000
# 02 alex 30000
# 03 lex 15000
# 04 ash 43000
# 05 bob 21000
# 06 faker 20000
# 07 boss 99999