awk简介
awk的命名是由其三位创始人的姓名首字母拼合而来,是一个非常厉害的数据处理工具。相较于同为文本三剑客之一的sed而言,sed常作用于一整个行的处理,awk则比较倾向于一行当中分成数个字段来处理。因此,awk相当的适合处理小型的数据。 awk的一般用法格式:
awk [options] ' pattern {action statements;…} ' file…
- pattern 部分决定动作语句何时触发及触发事件 包括 BEGIN 和 END
- action statements 对数据进行处理,放在{ }内指明 包括 printf 和 printf
- 分隔符、域和记录 awk执行时,由分隔符分隔的字段(域)标记的$1、$2…$n称为域标识。$0为所有域,这里的$和shell中的变量$不一样。 文件的每一行称为记录(因为内置变量RS默认为换行符) 省略action,则默认执行 print $0 的操作
awk的处理流程及内置变量
处理流程 1.读入第一行,并将第一行的资料填入$0,$1,$2…等变数当中; 2.依据“条件类型”的限制,判断是否需要进行后面的“动作”; 3.做完所有的动作与条件类型; 4.若还有后续的【行】的数据,则重复上面1~3的步骤,知道所有的数据都读完为止。 内置变量 由上述的流程我们可以知晓,awk是以行为一次的处理单位,而以字段为最小的处理单位。那么awk是怎么知道数据得行数和字段数,这就需要awk内置变量了。
变量名称 | 变量意义 |
---|---|
NF | 每一行($0)拥有的字段总数 |
NR | 目前awk所处理的是“第几行” |
FS | 目前的分割字符,默认是空格键 |
RS | 输入记录分隔符,默认一行为一条记录 |
我们长用到的内置变量就是如上这些,但是除了内置变量的应用,还有awk的逻辑运算符,也在awk的应用中起到很重要的作用。 awk逻辑运算符
运算符 | 代表意义 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
值得注意的是那个“==“的符号,因为:
- 逻辑运算上面也就是所谓的大于、小于、等于等判断式上面,习惯上是以”==”来表示;
- 如果是直接给予一个值,例如变量设置时,就直接使用=而已。
awk控制语句
if-else 语法:
if(condition){statement;…} [else statement]
if(condition1){statement1} else if(condition2){statement2} else{statement3}
例:当第三列uid大于1000打印“common user”,否则打印“root or Sysuser”
awk -F: '{if($3>=1000) printf "Common user: %s\n",$1;
else printf "root or Sysuser: %s\n",$1}' /etc/passwd
while循环
语法:
while(condition){statement;…}
条件为“真”,进入循环;条件为“假”,退出循环 例:统计以空格开头首单词是linux16的记录的每个字段的字母数量
awk '/^[[:space:]]*linux16/ {i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
for循环
语法:
for(expr1;expr2;expr3) {statement;…}
例:将上例用for循环来做
awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
awk函数
gsub函数 要在整个记录中替换一个字符串为另一个,使用(正则表达式格式,/目标模式/,替换模式) 例如改变将序号111改成222:
echo "111hah111ih111j" |awk 'gsub(/111/,222){print $0}'
sub函数
使用sub发现并替换模式的第一次出现位置。对比gsub,sub只替换第一个匹配到的位置
例:任意改变上例的字符串
echo "111hah111ih111j" |awk 'sub(/111/,222){print $0}'
substr函数
substr是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。
例子如下:取出下列字符的前五个字符
echo "lishuyang" |awk '{print substr($1, 1,5)}'
length函数
返回所需字符串长度,例如检验某字符串返回名字及其长度,即字符串构成的字符个数。
例: 统计字符串“lishuyang”的长度
echo "lishuyang" |awk '{print length($0)}'
split函数
使用split返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔
符-,例如AD2-KP9-JU2-LP,将之划分成一个数组。使用split,指定分隔符及数组名。此
例中,命令格式为(“AD2-KP9-JU2-LP″,parts_array,”-“),split然后返回数组下标数,这
里结果为4。
awk 'BEGIN{print split("AD2-KP9-JU2-LP",parts_array,"-")}'
awk使用注意事项
- awk后续的所有动作是以单引号' ' 括住的,由于单引号与双引号都必须是成对的,所以,awk的格式内容如果想要以print打印时,非变量的文字部分都需要用双引号定义出来
- 内置变量NR,指的是记录分隔符,默认为一行为一条记录,也就是说将换行符作为默认的记录分隔符,如果令NR==” “,则没个空格后都是一条记。
- awk命令中定义变量有两种方式,一种是再shell环境中利用-v选项,即awk -v 设置变量;另一种方式则是再BEGIN部分或者partern部分直接设置变量。
- print是非格式化的 printf是带格式化的类似C语言
- BEGIN {action} : 读取文本之前进行的操作;END {action}: 它在整个输入文件处理完成后被执行,同样无法对文本进行任何操作,如匹配某个pattern执行action。