技术文

awk简易教程

2016-09-03  本文已影响0人  默念2009

导读

相对于 sed 常常作用于一整行的处理,awk 则比较倾向于将一行分成数个“字段”来处理。
本文翻译自 simple awk tutorial
习惯了英文者,可自行前往阅读。

接下来的例子中会使用到 employee.txt 文件。
$ cat employee.txt 100 Thomas Manager Sales $5,000 200 Jason Developer Technology $5,500 300 Raj Sysadmin Technology $7,000 400 Nisha Manager Marketing $9,500 500 Randy Manager Sales $6,000

awk是做什么的?

最简单的 awk 用法是基于列的数据处理,比如说表格,使用标准输入将数据导入。变量 $1, $2...表示当前输入行的第一列,第二列...。打印出一个文件的第二列,你可能会使用下面的 awk 脚本:

awk < file '{ print $2 }'

这意味着“每一行,打印出第二个字段”

例如:
$awk < employee.txt '{ print $2 }' Thomas Jason Raj Nisha Randy

为了打印出第二列和第三列,可以

awk < file '{ print $2, $3 }'

分隔符

awk 将行分隔为字段,默认会使用空白符(whitespace)来分隔,也就是空格符(spaces)或制表符(tabs)。 你可以使用 -F 选项来指定其它字符为分隔符。例如,为了打印出当前系统中所有用户的主目录,你可以

$awk < /etc/passwd -F: '{ print $6 }'

passwd 的文件内容以冒号来分隔,主目录在第六个字段。

运算

awk是一种弱类型语言;变量既可以是字符串,也可以是数字,这取决于你怎样引用它们。所有的数字都是浮点型的。所以,为了实现华氏温度与摄氏温度之间的转换,你可以

awk '{ print ($1-32)*(5/9) }'

标准输入的华氏温度会被转换为摄氏温度,直到遇到 EOF,该 awk 程序停止。

可选的操作符与C基本一样。紧接着的两个字符串表达式(以空格分隔或没有空格),会连接。‘+’ 总是加法。

echo 5 4 | awk '{ print $1 + $2 } 会输出 “9”,然而
echo 5 4 | awk '{ print $1 $2 }' 会输出 “54”,注意
echo 5 4 | awk '{ print $1, $2 }' 会输出 “5 4”。

变量

awk 有一些内置的、自动置值的变量,比如上文提到的$1。其它的内置变量中,适合初学者的,也就是 $0 和 NF 了,前者表示当前输入行,后者表示当前输入行($0)的字段总数。$NF表示当前输入行的最后一个字段。

你可以定义自己的变量,除了 awk 保留的关键词,你可以用任何名字来引用它。变量没有明确赋值的,字符串为“”,数字为0。

例如,下面的代码会打印出每行数字的平均值:

awk '{ tot=0; for (i=1; i <= NF; i++) tot += $i; print tot/NF; }'

使用 $i 去取第 i 个变量的值, for 循环与C语言类似。 tot 在代码的开头作初始化的原因,是这个代码运行于每一个输入行,如若不,当开始运行第二行的时候, tot 将具有第一行结束时的值。

块Block

可能,你仅有一些特殊字段的数字需要单独相加。为了这样做,你需要在结束时打印结果。采用的方法为

awk '{ tot += $1; n += 1; } END { print tot/n }'

注意两个语句块的使用。第二个之前有个 END;意味着一旦所有的输入处理结果,就运行这个语句块。一般,你可以在语句块之前添加各种条件,仅当条件满足时语句块才被执行。也就是,你可以

awk '$1 == 0 { print $2 }'

仅在第一个字段为0时才打印第二个字段。你还可以使用正则表达式来匹配行数据:

awk '/^test/' { print $2 }

如果你没有添加条件,每行数据输入时都会运行块语句。

语句块的特殊条件 BEGIN 和 END,分别运行于输入数据的处理之前和处理之后。

printf

awk 包含了 printf 语句,本质上类似于C语言的 printf。当你想要格式化输出,或者将多种元素整合到一行,可以使用它。(print 暗含增加一个'\n';printf不会)。

比如,移除每一行第一字段

awk '{ for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n"; }'

注意,使用NF迭代所有的字段,显示地使用 printf 输出 '\n'。

上一篇下一篇

猜你喜欢

热点阅读